2009-06-10 1 views
7

Structure Map에서 mvc.net을 사용하여 모든 저장소와 서비스를 검색하고 등록합니다. 이제 싱글 톤으로 등록하고 캐시하고 싶습니다. 어떻게해야합니까?어셈블리에서 자동 스캔 유형으로 구조 맵을 구성하고 싱글 톤으로 캐시하는 방법은 무엇입니까?

IContainer container = new Container(x => { 
      // Register Repositories and Services 
      x.Scan(y => { 
       y.AssemblyContainingType<SomeRepository>(); 
       y.AssemblyContainingType<SomeService>(); 

       y.IncludeNamespaceContainingType<SomeRepository>(); 
       y.IncludeNamespaceContainingType<SomeService>(); 
      }); 

      // Register Controllers 
      x.Scan(y => { 
       y.TheCallingAssembly(); 
       y.AddAllTypesOf<IController>().NameBy(type => type.Name.Replace("Controller", "")); 
      }); 
     }); 

답변

19

2.6의 새 API를 사용하면 ITypeScanner가 더 이상 사용되지 않습니다. 이것은 대신 협약으로 이행되어야한다.

Scan(a => 
    { 
     a.AssemblyContainingType<IMyPluginType>(); 
     a.With(new SingletonConvention<IMyPluginType>()); 
     a.AddAllTypesOf<IMyPluginType>(); 
    }); 

다음 :

internal class SingletonConvention<TPluginFamily> : IRegistrationConvention 
    { 
     public void Process(Type type, Registry registry) 
     { 
      if (!type.IsConcrete() || !type.CanBeCreated() || !type.AllInterfaces().Contains(typeof(TPluginFamily))) return; 

      registry.For(typeof(TPluginFamily)).Singleton().Use(type); 
     } 
    } 
+0

+1 BTW, 전화 할 필요가 없습니다. a.AddAllTypesOf (); Scan()에서는 SingletonConvention.Process()가 해당 유형을 등록합니다. – ozczecho

+0

왜 'Scan'에 3 줄이 필요합니까? 'a.With (새로운 SingletonConvention ());와'a.AddAllTypesOf ();'의 차이점은 무엇입니까? 그 두 가지는 정말로 필요한가요? 다른 인터페이스가있는 경우 두 줄을 다시 사용해야합니까? – tyron

+0

지나치게 장황하지만 챔피언처럼 일했습니다. 진술은 사용해야한다고 생각하지만 API를 변경하지는 않을 것이라고 생각합니다. 나는 API를 바꾸지 않을 것이라고 말한 후에도 여전히 더 잘할 수 없다는 것을 의미하지는 않습니다. –

2

당신은 내가 할 그 스캔 전화를 바꿀 것, 제레미 밀러 http://codebetter.com/blogs/jeremy.miller/archive/2009/01/20/create-your-own-auto-registration-convention-with-structuremap.aspx 예를 들어 당신의 컨트롤러에 대한 그래서

에 설명 것과 유사한 ITypeScanner를 구현해야합니다 :

x.Scan(y => { 
    y.TheCallingAssembly(); 
    y.With<MyNewTypeScanner>(); 
}); 

그런 다음 다른 클래스를 다음과 같이 정의합니다.

public class MyNewTypeScanner: ITypeScanner 
{ 
    //This method is responsible for determining if a type should be registered 
    // and then passing it to RegisterType() if so 
    public void Process(Type type, PluginGraph graph) 
    { 
     //At this point you would probably just test to see if type is IController 
     //but you can get more sophisticated without too much headache. 

     this.RegisterType(graph, type); 
    } 


    private void RegisterType(PluginGraph graph, Type implementingType) 
    { 
     //The argument passed to FindFamily must be the type/class that will be requested out of SM 
     var family = graph.FindFamily(implementingType); 

     family.AddType(implementingType); 
     family.SetScopeTo(InstanceScope.Singleton); 
    } 
} 

이것은 당신을 위해 트릭을해야합니다.

0

@Eric 하우저의 대답에 확장보다 쉽게 ​​사용할 수를 생성하는 간단한 예제는 특정 인터페이스의 모든 종류의 싱글이다 컨벤션을 등록 할 것입니다 한 번이 설립 기본 클래스와 솔루션

public abstract class TypedRegistrationConvention<TPluginFamily> 
             : IRegistrationConvention 
{ 
    public virtual void Process(Type type, Registry registry) 
    { 
     if (!type.IsConcrete() 
      || !type.CanBeCreated() 
      || !type.AllInterfaces().Contains(typeof (TPluginFamily))) 
      return; 

     ApplyConvention(type, registry); 
    } 

    public abstract void ApplyConvention(Type type, Registry registry); 
} 

, 당신은 다음 유형 검사 코드 주위에 정처없이 규칙을 구현할 수 있습니다.

public class SingletonConvention<TPluginFamily> 
           : TypedRegistrationConvention<TPluginFamily> 
{ 
    public override void ApplyConvention(Type type, Registry registry) 
    { 
     registry.For(typeof (TPluginFamily)).Singleton().Use(type); 
    } 
} 

결국 훨씬 간단한 클래스입니다.

관련 문제