2014-02-09 9 views
1

코드는 from입니다. Unity는 Account 유형의 모든 명명 된 등록을 해결해야하며이를 일반 배열로 지정해야합니다. 그러나 어떤 이유로 든 Account 종속성이 해결되지 않으므로 주입 된 일반 배열은 비어 있습니다. 배열에 데이터가 채워지지 않는 이유는 무엇입니까?주사 된 제네릭 배열에 구성 요소가 없습니다.

container.RegisterType<Account>("first"); 
    container.RegisterInstance<Account>("second", new Account()); 

    container.RegisterType(
     typeof(MyClass<>), 
     new InjectionConstructor(
      new GenericResolvedArrayParameter("T"))); 

    var myClass = container.Resolve<MyClass<Account>>(); 
    Console.WriteLine(myClass.InjectedValue.Length); // 0 

public class Account 
{ } 

public class MyClass<T> 
{ 
    public T[] injectedValue; 

    public MyClass(T[] injectedValue) 
    { 
     this.InjectedValue = injectedValue; 
    } 

    public T[] InjectedValue 
    { 
     get { return this.injectedValue; } 
     set { this.injectedValue = value; } 
    } 
} 

감사

+0

"구걸 버그"특히 제목에서. – user2864740

+0

왜 배열이 * any * 크기이고, 더 적은 * 모든 * 비 * null 값을 가질 수 있습니까? 즉, 위의 규칙에 따라 유니티에 어레이에 주입 할 내용을 알릴 수 있습니까? – user2864740

+0

@ user2864740 : Account [] 유형의 배열이 제네릭이 아닌 경우 Unity는 등록 된 각 계정 유형에 대한 인스턴스를 만들어 해당 배열에 삽입합니다. 포함 된 링크에 따르면 배열이 일반 일 때 같은 일이 발생합니다 – bckpwrld

답변

1

당신은 단지 하나의 일반적인 매개 변수 T를 사용하는 생성자를 선택 유니티 도움이 될 것입니다 사용하는 코드입니다. 그러나 어떤 인스턴스를 제공할지는 알려주지 않습니다.

당신은 당신이로 주입하려는 명명 된 인스턴스 지정 GenericResolvedArrayParameter을 사용할 수 있습니다

:

var container = new UnityContainer(); 
container.RegisterType<Account>("first"); 
container.RegisterInstance<Account>("second", new Account()); 

container.RegisterType(
    typeof(MyClass<>), 
    new InjectionConstructor(
     new GenericResolvedArrayParameter(
      "T", 
      new GenericParameter("T", "first"), 
      new GenericParameter("T", "second")))); 

를 사용하면 사용자가 지정한대로 (여러 생성자가있는 경우 그러나이 조금 복잡하고, 단지 정말 유용하다 생성자해야 유니티 사용) 또는 명명 된 등록 중 일부를 전달하려는 경우 (수동으로 포함하는 경우). 운 좋게도 Unity는 기본적으로 배열을 이해하고 모든 명명 된 인스턴스를 제공합니다. 그래서 당신은 (그것을 구체적인 형태이기 때문에) T[] 당신이 전혀 MyClass에 대한 등록이 필요하지 않습니다 복용 하나의 생성자가있는 경우 :

그냥 당신이 MyClass<Account>를 해결하기 위해 시도 할 수 있음을 수행하여
var container = new UnityContainer(); 
container.RegisterType<Account>("first"); 
container.RegisterInstance<Account>("second", new Account()); 
var defaultInstance = new Account(); 
container.RegisterInstance<Account>(defaultInstance); 

하고, "first"와 "second"라는 이름의 등록이 주입 된 것을 볼 수 있습니다.

var myClass = container.Resolve<MyClass<Account>>(); 
//myClass.injectedValue contains 2 items, from registrations "first" and "second" 
//default (unnamed) registration is skipped 

대신 당신이 IEnumerable<T> 같은 다른 열거 유형이 T[] 배열 매개 변수가있는 생성자의 경우에도이 마지막 방법을 사용할 수 있습니다. 나는 4 접근 방식을 테스트 this fiddle을 만든

container.RegisterType<IEnumerable<Account>,Account[]>(); 

: 그냥 원하는 열거 형으로 배열에서 매핑하는 방법을 통일 알려줍니다 다른 등록을 추가 할 수 있습니다. 이러한 옵션의 작동 방식을 이해하면 도움이되기를 바랍니다.

+0

감사합니다. 이 코드는 생성자를 선택하는 방법 만 보여주기위한 것이라는 것을 깨닫지 못했습니다. 나는 또한 해결 된 명명 된 등록으로 배열을 채우기로되어 있다고 생각했습니다. 하지만 다시 그 기사를 읽는 것은 치아를 당기는 것과 같습니다. – bckpwrld

+0

예, 그 기사는 따라하기가 어렵습니다! [Unity 3]에 대한 msdn 항목 (http://msdn.microsoft.com/en-us/library/dn170416.aspx)은 다소 나아졌으며 적어도 따르기가 더 쉽습니다. 또한 초기 등록 코드는 명명 된 등록 중 일부만 배열에 전달하려는 경우 유용 할 것이라고 언급하는 것을 잊어 버렸습니다 (해당 설명을 포함하도록 답변을 업데이트했습니다) –

관련 문제