使用 Unity 注入数组

发布于 2024-12-17 03:40:09 字数 491 浏览 1 评论 0原文

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

以下是我目前的方式。

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 还是有更标准的方法来完成同样的事情?

My goal is to constructor inject an array of objects implementing an interface.

The following is the way I currently have it.

Container

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

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

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

Is it typical to call Resolve in container configuration this way or is there a more standard way to accomplish the same thing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

公布 2024-12-24 03:40:09

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>();

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

Unity natively understands arrays, so there's no reason to make it so complicated. Just register the ILoaders you want to include and resolve the object graphs normally. Auto-wiring will take care of the rest:

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

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

assuming that the MyConsumer constructor is defined like this:

public MyConsumer(ILoader[] loaders)

However, you should be aware that (for some unfathomable reason) Unity only includes named components in this way. The default component:

container.RegisterType<ILoader, Loader>();

will not be included in the array, since it has no name.

惜醉颜 2024-12-24 03:40:09

如果您有一个稍微复杂的场景,其中必须在不同的地方使用不同的值数组,那么您可以使用 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");

If you have a slightly more complicated scenario where different arrays of values have to be used in different places, then you can use ResolvedArrayParameter, e.g.

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");
皇甫轩 2024-12-24 03:40:09

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

您还可以通过注册 ILoader[] 类型并使用采用 RegisterType 重载(需要一个姓名。

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

Using Resolve during "configuration time" is acceptable and often useful, and it's perfectly valid for arrays or enumerables.

You could also have done the above by registering the ILoader[] type and registering each of the specific ILoader types using the RegisterType overload that takes a name.

Then, wherever ILoader[] is required (e.g. needs to be injected), all of the above will resolve for you after configuration time. Of course, if you need multiple/different ILoader[] it would devolve back to needing to use Resolve during configuration time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文