2010-01-29 7 views
33

내 개체를 확인하는 데 Unity IoC 컨테이너를 사용하고 있습니다. 그러나 문제가 생겼습니다. 하나 이상의 생성자가있을 때 - 유니티는 어떤 것을 사용할지를 어떻게 알 수 있습니까? 하나가 있고 하나도없는 경우 매개 변수가있는 매개 변수를 사용하는 것 같습니다. 명시 적으로 사용할 생성자를 말할 수 있습니까?Unity IoC 컨테이너에 사용할 생성자를 지정하십시오.

특히 두 개의 생성자가있는 다음 Person 클래스와 비슷한 케이스가있었습니다. 이 경우 IoC 컨테이너에서 매개 변수없이 기본 생성자를 사용하지만 매개 변수가있는 컨테이너를 선택합니다.

public class SomeValueObject 
{ 
    public SomeValueObject(string name) 
    { 
     Name = name; 
    } 
    public string Name { get; set; } 
} 

public class Person 
{ 
    private string _name; 

    public Person() 
    { 
     _name = string.Empty; 
    } 

    public Person(SomeValueObject obj) 
    { 
     _name = obj.Name; 
    } 
} 

이것은 분명히 SomeValueObject를 만들 수 없어서 실패합니다. 즉, 문자열 매개 변수에 무엇을 주입해야하는지 알지 못합니다. 그 오류는 다음과 같습니다.

"MyApp.Person", name = ""을 (를) 입력하지 못했습니다. 예외 메시지 : 현재 빌드 작업 (빌드 키 [빌드 키 [MyApp.Person, null]) 실패 : 생성자 MyApp.Person (MyApp.SomeValueObject obj)을 호출 할 때 매개 변수 obj를 확인할 수 없습니다. (전략 형 BuildPlanStrategy 인덱스 3)

용기 등록 :

Container.RegisterType<Person, Person>(new Microsoft.Practices.Unity.ContainerControlledLifetimeManager()); 

그리고 해결은 :

var person = Container.Resolve<Person>(); 
+0

인터페이스를 사용하는 IoC의 요점은 무엇입니까 ??? – Martin

+3

물론, 나는 그것을 대부분합니다. 그러나 이것은 질문에 영향을 미치지 않았습니다. – stiank81

+0

@Martin 많은 프로그래머가 클래스를 사용하고 인터페이스를 만든 다음 하나의 인터페이스 만 구현하는 가짜 일반성을 피합니다. 또한 대부분의 엔터프라이즈 애플리케이션에서 볼 수있는 철저한 IoC 배선 문제를 피할 수 있지만 필요에 따라 일부 구현을 전환 할 수도 있습니다. http://programmers.stackexchange.com/questions/133471/writing-testable-code-vs-avoiding-speculative-generality –

답변

46

이 대신처럼 등록

container.RegisterType<Person>(new InjectionConstructor()); 

당신은 REGISTERTYPE 방법의 오버로드를 사용하여뿐만 아니라 LifetimeManager를 추가 할 수 있습니다.

즉 DI를 모델링 할 때 명백한 컨스트럭터가있는 경우 (즉, 과부하 된 생성자가없는 경우) 훨씬 쉽게 작업 할 수 있습니다.

+0

당신은 어떤 과부하를 참조하고 있습니까? – Casey

+0

@Casey ... 나는 빈 생성자를 믿는다. – granadaCoder

+0

InjectionConstructor에 대한 인수가 없으므로 Person의 빈 생성자를 호출하고 있습니다. 코드가 'new InjectionConstructor (new SomeValueObject ("John Smith"))'였으면 다른 (other) 생성자를 호출했을 것입니다. "다른"생성자는 SomeValueObject 객체/인수를 사용하는 생성자입니다. – granadaCoder

4

Multiple-Constructor Injection Using an Attribute

목표 클래스 이상을 포함 할 때 하나의 생성자 w 같은 수의 매개 변수 i 번째, 당신은 유니티 컨테이너 이 컨테이너가 사용해야하는 생성자 표시하기 위해 사용하는 생성자에 InjectionConstructor 속성를 적용해야합니다. 자동 생성자 주입과 마찬가지로 생성자가 구체적인 유형으로 매개 변수 지정하거나 유니티 컨테이너가 등록 된 매핑을 포함하는 위한 인터페이스 또는 기본 클래스를 지정할 수 있습니다.

22

기본적으로 Unity는 최대 인수 개수의 생성자를 선택합니다. 이를 오버라이드하려면 필요한 생성자를 InjectionConstructorAttribute으로 꾸미십시오.

+4

생성자를 꾸미면 유니티를 IoC 컨테이너로 연결한다는 것을 언급해야합니다. 등록시 사양을 처리하는 것이 아마도 구성 요소가 Unity에 대한 참조를 취할 필요가 없으므로 바람직하기 때문에 다른 IoC를 스왑 아웃 할 수 있도록하는 것이 좋습니다. –

0

필자는이 인스턴스에서 종속성 주입을 사용하는 방식이 실제로 잘못되었음을 지적해야합니다. 컨테이너는 생성시 SomeValueObject를 주입 할 수 있어야합니다.

가장 일반적으로 할 일은 SomeValueObject의 기본 개체를 등록하는 것입니다.Name 속성은 string.Empty을 대신 반환합니다.

+0

아마 내 간단한 예제는 약간 떨어져 있지만, 실제 코드에는 두 개의 다른 생성자가 필요합니다. 어쨌든 언급 해 주셔서 감사합니다. – stiank81

+0

작성하지 않으 셨다면 어떻게해야합니까? – Casey

관련 문제