Passing an array into a constructor of ResolvedArrayParameter

Feb 13, 2014 at 10:09 PM
Edited Feb 13, 2014 at 10:12 PM
Hi

From:
class MyClass
{
public MyClass(ILogger[] myLogger) {}
}

The following example code injects a specific instance, myLogger, of an array, ILogger, into MyClass.


container.RegisterType<MyClass>(
new InjectionConstructor(new ResolvedArrayParameter<ILogger>(myLogger)));

By using ResolvedArrayParameter as a constructor parameter you will get the registered instances of the specified array, myLogger. At resolve time, the container calls ResolveAll<ILogger> and injects the resulting array into the constructor.
Is the quote saying that if we pass myLogger array into a constructor of ResolvedArrayParameter, then all named registrations of ILogger will be resolved and placed into the resulting array? But that doesn't seem to be the case, since the following example shows that only elements contained by myLogger array will be placed into resulting array :
            var logger1 = new Logger1();
            ILogger[] myLogger = new ILogger[] { logger1 };

            container.RegisterType<ILogger, Logger2>("named");

            container.RegisterType<MyClass>(
                new InjectionConstructor(
                    new ResolvedArrayParameter<ILogger>(
                        myLogger)));

            var result = container.Resolve<MyClass>();

            Console.WriteLine(myLogger.Length);           // 1
            Console.WriteLine(myLogger[0] is Logger1); // true
thanks
Feb 15, 2014 at 7:00 AM
Based on your last few questions, it looks like you are digging into Unity. If you haven't read it already, I recommend the Developer's Guide to Dependency Injection Using Unity.

I agree that the quote is contradictory. ResolvedArrayParameter lets you explicitly specify what array you want injected. If you are using arrays then you can just tell Unity what constructor you want and it will inject the all named registrations as an array.

So if wanted to inject a "named" Logger2 instance as an array you would just register the InjectionConstructor type:
container.RegisterType<MyClass>(
    new InjectionConstructor(typeof(ILogger[])));

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Feb 16, 2014 at 8:01 PM
randylevy wrote:
Based on your last few questions, it looks like you are digging into Unity. If you haven't read it already, I recommend the Developer's Guide to Dependency Injection Using Unity.
I tried reading it ( downloaded it as DIPwithUnity.pdf ) after I've finished DIP in Net by Seeman. While I've managed to digest Seeman's book in just a few days, this pdf is like pulling teeth. Text is so confusing and ambiguous, that it manages to confuse even when describing a concept the reader is totally familiar with. So I did crawl up to page 30, but then all my nails were gone due to biting them veraciously, so I had no choice but stop reading it

Instead I opted for trial and error approach, where I learn how Unity behaves by trying different combinations of configurations etc.


Msdn articles on Unity 2 are much clearer, though at times they still are way more confusing and ambigous than they should be. Here's are two examples ( from ) of what I'm talking about ( and if you find some time, I'd appreciate if you'd help me with the question ):

a)
Using the RegisterInstance method to register an existing object results in the same behavior as if you just registered the lifetime container with RegisterType. Therefore, it is recommended that you do not use the RegisterInstance method to register an existing object when using the non-default lifetime managers except for the thread in which the RegisterInstance was invoked.
The confusing part:
... when using the non-default lifetime managers except for the thread in which the RegisterInstance was invoked.
What is the above excerpt trying to convey? That in other threads we should only use __RegisterInstance __ when using default lifetime managers, but in thread where it was invoked we can use it even if using non-default lifetime managers?

b)
If you registered an existing instance of an object using the RegisterInstance method, the container returns the same instance for all calls to Resolve or ResolveAll or when the dependency mechanism injects instances into other classes, provided that one of the following is true:
• ...
• You are resolving in the same context in which you registered the instance when using a different lifetime manager.
I understand that we'll get same instance for all calls to Resolve if this instance is resolved in the same context in which we called RegisterInstance . But I don't get what they meant by "using a different lifetime manager"

thanks much for your help

Anyways, thank you for your help
Feb 17, 2014 at 12:15 AM
Using the RegisterInstance method to register an existing object results in the same behavior as if you just registered the lifetime container with RegisterType. Therefore, it is recommended that you do not use the RegisterInstance method to register an existing object when using the non-default lifetime managers except for the thread in which the RegisterInstance was invoked.
This is just a recommendation and not a hard rule. I think what this is saying that it is recommended to not use RegisterInstance with non-default (i.e. non-container-controlled lifetime managers) except for when registering on a thread using PerThreadLifetimeManager. But I agree that it is confusing.
• You are resolving in the same context in which you registered the instance when using a different lifetime manager.
I think they are just being formally correct in describing situations where objects are treated as Singletons. "using a different lifetime manager" in this sense means the non-default lifetime manager (non container-controlled lifetime manager). e.g. PerThreadLifetimeManager in the context of the same thread returns a singleton in that context or HierarchicalLifetimeManager in the context of one child container. Those are the third set of scenarios where objects are singletons.


~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to