2010-03-19 5 views
4

저는 Autofac을 사용하고 있습니다. 생성자 매개 변수에 적용하는 특성을 기반으로하는 다른 종속성 구현을 삽입하려고합니다. 예를 들면 다음과 같습니다.생성자 매개 변수 속성을 기반으로 autofac과의 종속성을 확인하십시오.

class CustomerRepository 
{ 
    public CustomerRepository([CustomerDB] IObjectContainer db) { ... } 
} 

class FooRepository 
{ 
    public FooRepository([FooDB] IObjectContainer db) { ... } 
} 

builder.Register(c => /* return different instance based on attribute on the parameter */) 
     .As<IObjectContainer>(); 

속성은 올바른 객체를 인스턴스화하는 데 사용할 수있는 연결 문자열과 같은 데이터를 제공합니다.

어떻게하면됩니까?

답변

9

CustomerRepositoryFooRepositoryIObjectContainer의 다양한 구현을 제공하려는 것 같습니다. 이 경우 속성은 thin metal ruler 일 수 있습니다. 대신 Autofac을 사용하여 여러 구현을 구현하는 방법을 알려 드리겠습니다.

(예 : .ContainerScoped()로 통화가 간결 탈락되었다.)

첫째, 등록 명명하여 각 연결 문자열에 대한 IObjectContainer의 버전을 등록 : 다음

builder 
    .Register(c => new ObjectContainer(ConnectionStrings.CustomerDB)) 
    .As<IObjectContainer>() 
    .Named("CustomerObjectContainer"); 

builder 
    .Register(c => new ObjectContainer(ConnectionStrings.FooDB)) 
    .As<IObjectContainer>() 
    .Named("FooObjectContainer"); 

을, 특정 인스턴스를 해결 리포지토리 등록에서 :

builder.Register(c => new CustomerRepository(
    c.Resolve<IObjectContainer>("CustomerObjectContainer")); 

builder.Register(c => new FooRepository(
    c.Resolve<IObjectContainer>("FooObjectContainer")); 

이렇게하면 리포지토리에 구성 정보가 없습니다.

class CustomerRepository 
{ 
    public CustomerRepository(IObjectContainer db) { ... } 
} 

class FooRepository 
{ 
    public FooRepository(IObjectContainer db) { ... } 
} 
+0

대단한 답변을 보내 주셔서 감사합니다. 리포지토리의 구성을 자유롭게 유지하는 것이 중요합니다. 그러나 AutoFac이 서비스 선택과 관련하여 상황에 민감한 방식을 제공 할 수 있기를 바랍니다. 나는 Ninject가 이것을 할 수 있다는 것을 알고 있습니다. 대신 Func 를 주입하는 경로를 따라갈 수도 있습니다. 그렇게하면 저장소가 원하는 것을 결정할 수 있습니다. –

+2

Autofac (소문자 f)은 사용자가 원하는 모든 종류의 사용자 정의 문맥에 민감한 구조를 문자 그대로 지원할 수 있습니다. 이것은'Register '가 람다 식 ('Func <>')을 받아 들일 수 있고, 식 트리를 사용하여 람다 식을 만들 수 있기 때문입니다. (http://msdn.microsoft.com/en-us/library/bb397951.aspx) . 즉, 리플렉션을 사용하여 사용자 정의 구성을 실행하는 데 필요한 모든 람다를 빌드 할 수 있습니다. –

+0

리포지토리가 연결 문자열에 연결되도록하려면 속성 또는 인수를 사용하여 'Func '에 연결해야합니다. 응답으로 묻습니다 : 왜 저장소가 연결 문자열을 알아야합니까? 'IObjectContainer'를 만드는 데 필요한 것이 있다면, * that * 유형의 설정에 대한 책임이 아닙니까? 왜 저장소는 연결 문자열이 전혀 연관되어 있지 않다는 것을 알아야합니까? 왜 단순히'IObjectContainer'를 받아들이지 않습니까? –

0

몇 가지 저장소가 있고 생성자 매개 변수가 거의없는 경우 Bryan의 대답은 충분합니다. 그러나 루트가 많을 때 루트를 설정하는 것은 어렵습니다. 인터페이스를 분석 할 때 클래스 메타 데이터를 검색하여이를 수행 할 수 있습니다. 매개 변수에 대한 정보를 얻으면 실제 구현을 해결할 수 있습니다. 내 대답 here을 참조하십시오.

관련 문제