Injecting arrays with Unity

后端 未结 3 1567
被撕碎了的回忆
被撕碎了的回忆 2020-12-17 20:19

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

The following is the way I currently have it.

Container

        .Reg         


        
相关标签:
3条回答
  • 2020-12-17 21:00

    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.

    0 讨论(0)
  • 2020-12-17 21:13

    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.

    0 讨论(0)
  • 2020-12-17 21:15

    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");
    
    0 讨论(0)
提交回复
热议问题