C# 统一注入阵列

C# 统一注入阵列,c#,dependency-injection,unity-container,C#,Dependency Injection,Unity Container,我的目标是构造函数注入一个实现接口的对象数组 以下是我目前拥有它的方式 Container .RegisterInstance<Company>(ParseCompany(args[1]) .RegisterInstance<eTargets>(ParseTargets(args[2])) .RegisterInstance<ILoader[]>(new ILoader[] { Co

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

以下是我目前拥有它的方式

Container

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

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

        .RegisterInstance<ILoader[]>(new ILoader[] {
            Container.Resolve<CustomerLoader>(),
            Container.Resolve<PaymentLoader(),
            Container.Resolve<InvoiceLoader() 
        });
容器
.RegisterInstance(解析公司(参数[1])
.RegisterInstance(解析目标(参数[2]))
.RegisterInstance(新ILoader[]{
Container.Resolve(),

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

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


然后,无论何时需要
ILoader[]
(例如需要注入),以上所有问题都将在配置时间后为您解决。当然,如果您需要多个/不同的
ILoader[]
在配置期间,它将退化为需要使用
Resolve

Unity天生理解数组,因此没有理由让它变得如此复杂。只需注册您想要包含并正常解析对象图的
iLoader即可。自动布线将负责其余的:

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

var c = container.Resolve<MyConsumer>();
但是,您应该知道(出于某种难以理解的原因),Unity仅以这种方式包含命名组件。默认组件:

container.RegisterType<ILoader, Loader>();
container.RegisterType();

将不包括在数组中,因为它没有名称。

如果您有一个稍微复杂的场景,需要在不同的位置使用不同的值数组,则可以使用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");
container.RegisterType(“foo”);
容器注册类型(“bar”);
容器注册类型(“baz”);
容器注册表类型(“boo”);
container.RegisterType(“c1”,
新注入构造函数(
新参数(
新解析参数(“foo”),
新解析参数(“bar”);
container.RegisterType(“c2”,
新注入构造函数(
新参数(
新解析参数(“baz”),
新的解析参数(“boo”);
var c1=容器解析(“c1”);
var c1=容器解析(“c2”);

不完全是深不可测的:原因是,如果同一类型需要多个条目,则必须添加一个名称,否则Unity会认为您实际上覆盖了前一个条目(这是禁止的)。@BrunoBrant“深不可测”,因为没有其他DI容器可以这样工作。有关详细信息,请参阅例如。
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");