Injecting arrays with Unity

回眸只為那壹抹淺笑 提交于 2019-12-18 04:48:06

问题


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?


回答1:


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.




回答2:


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



回答3:


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.



来源:https://stackoverflow.com/questions/8186017/injecting-arrays-with-unity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!