使用Unity注入数组

时间:2011-11-18 16:58:27

标签: c# dependency-injection unity-container

我的目标是构造函数注入一个实现接口的对象数组。

以下是我目前的方式。

Container

        .RegisterInstance<Company>(ParseCompany(args[1])

        .RegisterInstance<eTargets>(ParseTargets(args[2]))

        .RegisterInstance<ILoader[]>(new ILoader[] {
            Container.Resolve<CustomerLoader>(),
            Container.Resolve<PaymentLoader(),
            Container.Resolve<InvoiceLoader() 
        });

通常以这种方式调用容器配置中的Resolve,还是有更标准的方法来完成同样的事情?

3 个答案:

答案 0 :(得分:27)

Unity 原生地理解数组,因此没有理由让它变得如此复杂。只需注册要包含的ILoaders并正常解析对象图。 自动接线将负责其余工作:

container.RegisterType<ILoader, FooLoader>("foo");
container.RegisterType<ILoader, BarLoader>("bar");
container.RegisterType<ILoader, BazLoader>("baz");

var c = container.Resolve<MyConsumer>();

假设MyConsumer构造函数的定义如下:

public MyConsumer(ILoader[] loaders)

但是,您应该知道(出于一些不可思议的原因)Unity仅以这种方式包含命名的组件。 默认组件:

container.RegisterType<ILoader, Loader>();

包含在数组中,因为它没有名称。

答案 1 :(得分:4)

如果你有一个稍微复杂的场景,其中不同的值必须在不同的地方使用,那么你可以使用ResolvedArrayParameter,例如

container.RegisterType<ILoader, FooLoader>("foo");
container.RegisterType<ILoader, BarLoader>("bar");
container.RegisterType<ILoader, BazLoader>("baz");
container.RegisterType<ILoader, BooLoader>("boo");

container.RegisterType<IConsumer, MyConsumer>("c1",
    new InjectionConstructor(
        new ResolvedArrayParameter<ILoader>(
            new ResolvedParameter<ILoader>("foo"),
            new ResolvedParameter<ILoader>("bar"))));

container.RegisterType<IConsumer, MyConsumer>("c2",
    new InjectionConstructor(
        new ResolvedArrayParameter<ILoader>(
            new ResolvedParameter<ILoader>("baz"),
            new ResolvedParameter<ILoader>("boo"))));

var c1 = container.Resolve<MyConsumer>("c1");
var c1 = container.Resolve<MyConsumer>("c2");

答案 2 :(得分:3)

在“配置时间”期间使用Resolve是可以接受的并且通常很有用,并且它对于数组或枚举完全有效。

您也可以通过注册ILoader[]类型并使用ILoader重载注册每个特定RegisterType类型来完成上述操作。

然后,只要需要ILoader[](例如需要注入),上述所有内容都将在配置时间后为您解决。当然,如果您需要多个/不同的ILoader[],它将在配置时间内转回到需要使用Resolve