2011-10-02 46 views
2

我正在处理结构图错误很长一段时间。 错误是:StructureMap:Multithreaded env。没有为PluginFamily定义的默认实例

StructureMap.StructureMapException:StructureMap异常代码:202 为PluginFamily SomeNamespace.ISomeInterface没有定义默认实例,SomeNamespace,版本= 1.0.0.0, 文化=中性公钥=空

我们的项目是完全多线程的,可以每次使用不同的配置文件名称每秒调用一次结构图。

StructureMap设置在应用程序启动时完成。 我使用StructureMap.Configuration.DSL.Registry:

var registry = new Container(...some parameters settings...); 
StructureMap.ObjectFactory.Configure(x => x.IncludeRegistry(registry)); 

和集装箱是:

class Container : StructureMap.Configuration.DSL.Registry 
{ 
    public Container(...Some settings parameters...) 
    { 
     For<IConnG>().Use<DG>() 
      .Ctor<string>("user").Is(some parameter) 
      .Ctor<string>("pass").Is(some parameter) 
      .Ctor<string>("site").Is(some parameter) 
      .Ctor<string>("DateFormat").Is(some parameter); 

     For<IRPG>().Use<RPG>(); 

     Scan(asm => 
     { 
      asm.TheCallingAssembly(); 
      asm.Include(type => type.IsAbstract == false && type.IsSubclassOf(typeof(BaseC))); 
      asm.With(new RegistrationConvention()); 
     }); 

     var actionName = (enumA)Enum.Parse(typeof(enumA), some parameter); 

     switch (actionName) 
     { 
      case enumA.ActionA: 
       Profile(enumA.ActionA.ToString(), (pe) => 
       { 
        pe.For...; 
        pe.For...; 
        pe.For...; 
        pe.For<IXXX>().Use<DefaultXXX>(); 
        **pe.For<IAction<SomeNamespace.SearchParams, SomeNamespace.SearchParams>>().Use<DefaultSearchParams>();** 
        pe.For...; 
       }); 
       break; 

      case enumA.ActionB: 
       Profile(enumA.ActionB.ToString(), (pe) => 
       { 
        pe.For...; 
        pe.For...; 
        pe.For...; 
        pe.For<IXXX>().Use<DefaultXXX>(); 
        **pe.For<IAction<SomeNamespace.SearchParams, SomeNamespace.SearchParams>>().Use<DefaultSearchParams>();** 
        pe.For...; 
       }); 
       break; 

      case enumA.ActionC: 
       Profile(enumA.ActionC.ToString(), (pe) => 
       { 
        pe.For...; 
        pe.For...; 
        pe.For...; 
        pe.For<IXXX>().Use<DefaultXXX>(); 
        **pe.For<IAction<SomeNamespace.SearchParams, SomeNamespace.SearchParams>>().Use<XXXSearchParams>();** 
        pe.For...; 
       }); 
       break; 

      case enumA.ActionD: 
       Profile(enumA.ActionD.ToString(), (pe) => 
       { 
        pe.For...; 
        pe.For...; 
        pe.For...; 
        pe.For<IXXX>().Use<DefaultXXX>(); 
        **pe.For<IAction<SomeNamespace.SearchParams, SomeNamespace.SearchParams>>().Use<DefaultSearchParams>();** 
        pe.For...; 
       }); 
       break; 
     } 
    } 
} 

的RegistrationConvention是:

public class RegistrationConvention : StructureMap.Graph.IRegistrationConvention 
{ 
    #region IRegistrationConvention Members 

    public void Process(Type type, StructureMap.Configuration.DSL.Registry registry) 
    { 
     var interfaces = new List<Type> 
     { 
      type.GetInterface("IInfo`1"), 
      type.GetInterface("IBook`1"), 
      type.GetInterface("IConf`1"), 
      type.GetInterface("IClxP`1"), 
      type.GetInterface("ICanc`1"), 
      type.GetInterface("IConf2`1"), 
      type.GetInterface("IMaxP`1"), 
      type.GetInterface("IAction`1") 
     }; 

     interfaces 
      .ForEach(contractType => 
        { 
         if (contractType != null) 
         { 
          registry.For(contractType).Use(type); 
         } 
        }); 
    } 

    #endregion 
} 

我打电话StructureMap代码一样, :

var container = StructureMap.ObjectFactory.Container; 

container.SetDefaultsToProfile(Some profile name); 

var adaptor = container.GetInstance<IAction<SomeNamespace.SearchParams, SomeNamespace.SearchParams>>(); 

这段代码被很多线程调用,并且我得到这个错误的时间并不是所有的时间,但是相当多。 当打印出WhatDoIHave()时,它表示它有它。

我会很高兴有任何建议/更正。 在此先感谢。

回答

2

这很难解决,但最后我到了那里! 问题是我误用StructureMap: StructureMap,只要我正确地掌握了使用它的意图,就是为了在应用程序加载时动态加载一次设置。 在我们的项目中,我们每秒钟多次切换配置文件,并尝试基于该配置文件检索实例。虽然WhatDoIHave()显示了相反的结果,但我们得到了许多例外,因为它不能识别默认实例。 问题恰恰在于 - 从多个线程调用容器并在每个请求中切换配置文件。

所以,提醒,应用程序启动时,每个配置文件我加入其设置的唯一一个容器:

var registry = new OurRegistry(settings parameters..., profileName); 

StructureMap.ObjectFactory.Configure(x => x.IncludeRegistry(registry)); 

,并在代码中的许多地方,我习惯叫StructureMap这样的:

var container = StructureMap.ObjectFactory.Container; 

    container.SetDefaultsToProfile(profileName); 

    var adaptor = container.GetInstance<ISomeInterface<ConcreteType>>(); 

此代码并行使用,每个线程使用另一个配置文件。

因此,作为一个修复,我为每个配置文件创建一个容器!

var registry = new OurRegistry(settings parameters..., profileName); 

var container = new StructureMap.Container(registry); 

我存储在每个容器在我们的代码,而不是StructureMap像以前一样,所以每个配置文件多发线程使用它自己的异形容器。 这比以前更快,因为您不必切换配置文件,只有一次!

而没有更多#$ @!@ 202异常:)

相关问题