2010-03-18 8 views
31

여러 생성자가있는 클래스가있는 경우 - 사용할 생성자를 결정할 수있는 방법은 무엇입니까?Unity.Resolve는 사용할 생성자를 어떻게 알 수 있습니까?

다음 예제 클래스를 고려하십시오

public class Foo 
{ 
    public Foo() { } 
    public Foo(IBar bar) 
    { 
     Bar = bar; 
    } 
    public Foo(string name, IBar bar) 
    { 
     Bar = bar; 
     Name = name; 
    } 
    public IBar Bar { get; set; }   
    public string Name { get; set; } 
} 

내가 어떻게 사용할 생성자 알고 해결할 해결을 사용하여 Foo 타입의 객체를 만들려면

? 어떻게 올바른 것을 사용한다고 말할 수 있습니까? IBar가 등록 된 컨테이너가 있다고 가정 해 봅시다. IBar를 사용하는 생성자를 선호해야한다는 것을 이해합니까? 그리고 문자열을 지정하면 (string, IBar) 생성자가 사용됩니까?
Foo foo = unityContainer.Resolve<Foo>(); 

그리고 클래스는 단지 하나의 생성자가 있다면 아마 쉬울 것이라는 사실을 무시하세요

...

대상 클래스가 하나 이상의 생성자를 포함

답변

53

, 유니티는 하나를 사용합니다 InjectionConstructor 특성이 적용된 하나 이상의 생성자가 있고 아무 것도 InjectionConstructor 속성을 가지고 있지 않으면 Unity는 가장 많은 매개 변수를 가진 생성자를 사용합니다. 하나 이상의 생성자 (동일한 수의 매개 변수를 가진 "가장 긴"중 하나 이상)가있는 경우 Unity는 예외를 발생시킵니다.

container.RegisterType<Foo>(
    new InjectionConstructor(
     new ResolvedParameter<IBar>())); 

위의 코드는 메모리에서입니다,하지만 일반적인 원칙 : 당신이 유형을 등록 할 때

는 다음과 같이 사용할 생성자 지정할 수 link text

+0

좋아요. 감사..! – stiank81

+0

정확히 내가 무엇을 찾고 있었습니까! 그냥 [InjectionConstructor]와 함께 사용하고자하는 생성자를 꾸미십시오. –

+2

주말을 절약 할 수있는 대답입니다. 잘 정의 된. –

28

에서 촬영. 이 경우 IBar 형식의 단일 매개 변수를 사용하는 생성자를 선택했습니다.

그리고 클래스는 단지 하나의 생성자가 있다면 아마 쉬울 것이라는 사실을 무시하세요

...

나는이 문제를 무시할 수 없습니다. 생성자 주입에 관해서는 모호성은 디자인 냄새입니다. 당신은 기본적으로 다음과 같이 말하고 있습니다. 이 종속성에 관심이 있는지 없는지는 알 수 없습니다.

물론 Unity가 알아낼 가능성은 높지만 API를 올바르게 디자인하는 대신 특정 컨테이너 동작을 사용하게됩니다. 다른 컨테이너의 동작은 일 수 있습니다. 따라서 Unity에서 더 나은 컨테이너로 마이그레이션하도록 선택한 경우 미묘한 버그가 발생할 수 있습니다.

코드를 DI-friendly, but container-agnostic 방식으로 작성하는 것이 훨씬 안전합니다.

+0

감사! 하지만 실제로 컨테이너에 유형을 등록해야합니까? 나는 Foo의 인스턴스를 해결하기 위해 컨테이너를 사용할 것이지만 Foo가 컨테이너에 있어야 할 필요는 없습니다. 하지만 여전히 RegisterType을 사용해야합니까?아니면 단지 어떤 생성자에게 사용할 특별한 필요성이 있기 때문에? – stiank81

+0

예, 아니요. ozczecho가 인용 한 것처럼, Unity는 휴리스틱 접근법을 사용하여 모호성이있는 생성자를 선택합니다 (대부분의 매개 변수를 사용하여 생성자를 선택합니다). 이 알고리즘에서 벗어나게하려면이 알고리즘을 명시 적으로 말해야합니다. 한 가지 방법은 InjectionConstructor 특성을 적용하고 다른 하나는 컨테이너에 등록하는 것입니다. 나는 개인적으로 컨테이너에 타입을 등록하는 것을 선호한다. 왜냐하면 그것이 내 코드 컨테이너를 불가지론스럽게 유지할 수 있기 때문이다. 해당되는 경우 다른 컨테이너 구성도 허용합니다. –

+0

FWIW, 컨테이너에 아직 등록되지 않은 콘크리트 유형을 해결할 수있는 Unity의 기능은 그 기능입니다. 일부 컨테이너는 해당 기능을 지원하지만 다른 컨테이너는 지원하지 않습니다. –

관련 문제