2011-10-02 1 views
2

저는 구조대 오류를 처리하고 있습니다. 오류는 다음과 같습니다구조 맵 : 다중 스레드 환경 PluginFamily에 정의 된 기본 인스턴스가 없습니다.

StructureMap.StructureMapException : StructureMap 예외 코드 : PluginFamily SomeNamespace.ISomeInterface에 대해 정의 (202) 아니오 기본 인스턴스, SomeNamespace, 버전 = 1.0.0.0, 문화 = 중립, PublicKeyToken = null이

우리 프로젝트는 완전히 멀티 스레드이며, 매번 다른 프로필 이름으로 초당 여러 번 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은 : 그 같은 코드에 StructureMap를 호출하고있어

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 
} 

:

var container = StructureMap.ObjectFactory.Container; 

container.SetDefaultsToProfile(Some profile name); 

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

이 코드는 많은 스레드에 의해 호출되며이 오류가 항상 발생하는 것은 아니지만 꽤 많이 발생합니다. WhatDoIHave()를 인쇄 할 때 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 예외 :

관련 문제