2010-08-04 3 views
4

인터페이스를 생성자 인수로 사용하는 클래스가 있습니다. 이 인터페이스에는 두 가지 구현이 있으며 변수를 기반으로 런타임에 사용할 구현을 결정하고 싶습니다.동적 인 매개 변수가있는 자동 채우기 구성 요소

문제는 위의 클래스가 Autofac에 의해 해결되는 개체 계층 구조의 깊이이므로 문제를 전달할 수 없다는 것입니다.

아래와 같은 어싱은 내가 성취하고자하는 것입니다.

public interface IInterface1 {} 
public interface IInterface2 {} 

public class Class1 : IInterface2 
{ 
    public Class1(IInterface1 interface1) 
    { 
    } 
} 

public class Class2 
{ 
    public Class2(IInterface2 interface2) 
    { 
    } 
} 

public class Class3 
{ 
    public void GetClass2Instance(string interface1ImplementationToChoose) 
    { 
     // want to change which implementation of IInterface1 is resolved based on the interface1ImplementationToChoose variable 
     var class2 = container.Resolve<Class2>(); 
    } 
} 

아이디어가 있으십니까?

는 UPDATE :

명확히하려면이 잘 작동 기존의 응용 프로그램에서 사용되는 기존 개체 계층 구조입니다. 또한 객체 모델은이 예제에 표시된 것보다 훨씬 큽니다. 결과적으로 객체 그래프의 각 생성자에 대한 팩토리를 해당 그래프의 깊은 클래스에서 사용되도록 팩토리에 전달해야하는 것은 아닙니다.

IInterface1의 다른 구현이 Class2없이 Class1로 전달되도록하는 방법이 있습니까?

감사

+0

"이 인터페이스에는 두 가지 구현이 있습니다."하지만 샘플에는이 점이 잘 나타나지 않습니다. 정교하게 설명해 주실 수 있으시면 그에 따라 답변을 업데이트하겠습니다. –

답변

6

예, 유형을 선택하는 방법을 숨 깁니다 공장 주입 :

public class Class3 
{ 
    private Func<string, Class2> _class2Factory; 
    public Class3(Func<string, Class2> class2Factory) 
    { 
     _class2Factory = class2Factory; 
    } 

    public void GetClass2Instance(string interface1ImplementationToChoose) 
    { 
     var class2 = _class2Factory(interface1ImplementationToChoose); 
    } 
} 

을 그리고 컨테이너 설치 한 후,이 라인을 따라 뭔가 :

builder.RegisterType<Implementation1>().Named("imp1").As<IInterface1>(); 
builder.RegisterType<Implementation2>().Named("imp2").As<IInterface1>(); 
builder.Register<Func<string, Class2>>(c => 
    { 
     var context = c.Resolve<IComponentContext>(); 
     return imp => new Class2(context.Resolve<IInterface1>(imp)); 
    }); 
builder.RegisterType<Class3>(); 

당신은 지금 수를 다음과 같이 Class3을 사용하세요.

public class Class4 
{ 
    public Class4(Class3 class3) 
    { 
     var class2with1 = class3.GetClass2Instance("imp1"); 
     var class2with2 = class3.GetClass2Instance("imp2"); 
    } 
} 

참고 : 나는 동일한 인터페이스 IInterface1의 다양한 구현으로 Class2을 삽입해야한다는 것을 의미한다고 가정했습니다. 서로 다른 인터페이스를 구현하는 두 개의 클래스를 보여주기 때문에 샘플이 약간 혼란 스럽다.

+0

좋아 보인다. 또한 새로운 클래스 2 (context.Resolve (imp))이면 충분합니다 (참조를 유지하지 않으면 IComponentContext를 명시 적으로 확인할 필요가 없습니다.) –

+0

'Class2'를 새로 작성하는 것이 아닙니다. ,이 경우에는 자체 컨텍스트를 수행해야하는'Func '대리자를 등록합니다. 권리? –

+0

@Nicholas - Register 호출에 대한 대리자 형식을 지정해야한다는 것을 잊었습니다. 나는 람다에 "저장"할 새로운 문맥을 해결해야한다는 인상을 받고있다 ... –