2011-10-02 27 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異常:)

相關問題