注入的通用数组不包含任何组件

时间:2014-02-09 21:04:51

标签: generics dependency-injection unity-container

代码被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; }
    }
}

感谢

1 个答案:

答案 0 :(得分:1)

您正在使用的代码将帮助Unity选择一个采用单个通用参数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应该使用哪个构造函数)或者你只是想传递一些命名注册(当你手动包含它们时)才真正有用。幸运的是,Unity默认了解数组,并将提供所有命名实例。所以如果您有一个构建器使用T[] ,则根本不需要注册MyClass(因为它是具体类型):

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

通过这样做,您可以尝试解决MyClass<Account>,并且您会看到注册了“第一个”和“第二个”命名注册。

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

如果不是具有数组参数T[]的构造函数而是另一个类似IEnumerable<T>的可枚举类型,那么您仍然可以使用此最后一种方法。只需添加另一个注册,告诉Unity如何从数组映射到所需的可枚举类型:

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

我创建了this fiddle测试4种方法。 希望了解这些选项的工作原理会很有用。