2012-01-24 7 views
12

Autofac에는 모듈이 있고 윈저에는 설치자와 StructureMap 레지스트리가 있습니다 ... 간단한 인젝터로 어떻게 구성 논리를 재사용 가능한 클래스로 묶을 수 있습니까?간단한 인젝터로 모듈/인스톨러/레지스트리를 에뮬레이션하는 방법

public interface IModule { } 

public class FooModule : IModule 
{ 
    public FooModule(SimpleInjector.Container container) 
    { 
     container.RegisterSingleton<IBar, Bar>(); 
     container.RegisterSingleton<IFoo, Foo>(); 
    } 
} 

그리고 컴포지션 루트에서 사용 :

나는 시도

public static void Main(string[] args) 
{ 
    var container = new SimpleInjector.Container(); 
    container.RegisterCollection<IModule>(new FooModule(container)); 
    ... 
} 

그러나, FooModule 컨테이너에 의존하고 아마 좋은 연습에 ... 이 http://code.google.com/p/autofac/wiki/BestPractices 참조 :

구성 요소가 컨테이너에 종속 된 경우, 컨테이너를 사용하여 서비스를 검색하는 방법을 살펴보고 해당 서비스를 구성 요소의 (종속성 주입) 생성자 인수에 대신 추가하십시오.

+0

Autofac이있는 'FooModule'은 컨테이너 (또는 Autofac이 두 가지 유형으로 컨테이너를 분할하기 때문에 'ContainerBuilder'인 Autofac를 사용)에 따라 달라집니다. [이 Autofac 설명서] (http://code.google.com/p/autofac/wiki/StructuringWithModules)를 살펴보면 모듈이 이러한 종속성을 가짐을 분명히 알 수 있습니다. 모듈의 경우 컨테이너가 필요하지만 구성 루트에 모듈이 포함되므로 중요하지 않습니다. – Steven

답변

14

'모듈'기능은 의도적으로 Simple Injector 코어 라이브러리에서 제외되었지만이를 수행 할 수있는 SimpleInjector.Packaging NuGet package이 있습니다. '패키지'는 Simple Injector가 사용하는 용어입니다. 그러나이 라이브러리는 하나 이상의 IPackage 인터페이스와 두 가지 확장 방법입니다. 이 같은 코드를 작성하여 동일한을 얻을 수 있습니다

패키지 : 컴포지션 루트에서

public static class BootstrapperPackage 
{ 
    public static void RegisterServices(Container container) 
    { 
     container.Register<IBar, Bar>(Lifestyle.Scoped); 
     container.Register<IFoo, Foo>(Lifestyle.Singleton);    
    } 
} 

:

public static void Main(string[] args) 
{ 
    var container = new SimpleInjector.Container(); 

    BootstrapperPackage.RegisterServices(container); 

    ... 
} 

SimpleInjector.Packaging NuGet package와의 차이는이 패키지를위한 인터페이스를 정의하는 것입니다 그리고 한 줄에 여러 패키지를 동적으로로드 할 수 있습니다.

public class BusinessLayerPackage : IPackage 
{ 
    public void RegisterServices(Container container) 
    { 
     container.Register<IBar, Bar>(Lifestyle.Scoped); 
     container.Register<IFoo, Foo>(Lifestyle.Singleton);    
    } 
} 

public static void Main(string[] args) 
{ 
    var container = new SimpleInjector.Container(); 

    container.RegisterPackages(AppDomain.CurrentDomain.GetAssemblies()); 
} 
당신이 정말로 그렇게하지 않으면

그러나, 그것은 다음과 같은 장점을 가지고 있기 때문에, (위 그림 참조)이 바람직하다 정적 방법을 사용하여, 동적 로딩이 필요합니다

  • 로드 모듈은 매우 명시하고 검색 할 만듭니다.
  • 로드 할 모듈과로드하지 않는 모듈을 쉽게 선택할 수 있습니다.
  • 메서드에 여분의 값 (예 : 모듈에 필요한 구성 값)을 쉽게 전달할 수있게합니다. 이렇게하면 모듈이 구성 시스템에 크게 의존하지 않게됩니다.

자세한 내용은 this을 참조하십시오.

+0

감사합니다 스티븐,하지만 다른 클래스에 컨테이너를 전달하는 것이 맞습니까? – o3o

+0

아니요, 아니지만 모듈은 응용 프로그램 코드의 일부가 아니라 [composition root] (http://blog.ploeh.dk/2011/07/28/CompositionRoot)의 일부입니다.aspx),이를 인프라 구성 요소로 만듭니다. 인프라 구성 요소 내에서 컨테이너를 사용하는 것이 좋습니다. Mark Seemann은 이것을 명확하게 설명합니다 (http://blog.ploeh.dk/2011/08/25/ServiceLocatorRolesVsMechanics.aspx). – Steven

+1

이 기능이 코어 라이브러리에서 제외 된 이유는 무엇입니까? – Sam

관련 문제