Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injecting arrays with Unity

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?

like image 961
Aaron Anodide Avatar asked Nov 18 '11 16:11

Aaron Anodide


2 Answers

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.

like image 104
Mark Seemann Avatar answered Oct 27 '22 04:10

Mark Seemann


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");
like image 36
Paul Hatcher Avatar answered Oct 27 '22 05:10

Paul Hatcher