named type not used for constructor injection

May 5, 2010 at 6:03 AM

Hi,

I have a simple console application where I have the following setup:

 

public interface ILogger
{
    void Log(string message);
}

class NullLogger : ILogger
{
    private readonly string version;

    public NullLogger()
    {
        version = "1.0";
    }
    public NullLogger(string v)
    {
        version = v;
    }
    public void Log(string message)
    {
        Console.WriteLine("NULL> " + version + " : " + message);
    }
}
<type type="UnityConsole.ILogger, UnityConsole" mapTo="UnityConsole.NullLogger, UnityConsole">
  <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
    <constructor>
      <param name="message" parameterType="System.String" >
        <value value="2.0" type="System.String"/>
      </param>
    </constructor>
  </typeConfig>
</type>

 

My calling code looks as below:

 

IUnityContainer container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers.Default.Configure(container);
ILogger nullLogger = container.Resolve<ILogger>();
nullLogger.Log("hello");

 

But once I give a name to this type something like:

 

<type type="UnityConsole.ILogger, UnityConsole" mapTo="UnityConsole.NullLogger, UnityConsole" name="NullLogger">
  <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
    <constructor>
      <param name="message" parameterType="System.String" >
        <value value="2.0" type="System.String"/>
      </param>
    </constructor>
  </typeConfig>
</type>

 

The above calling code does not work even if I explicitly register the type using

 

container.RegisterType<ILogger, NullLogger>();

 

I get the error:

{"Resolution of the dependency failed, type = \"UnityConsole.ILogger\", name = \"\". Exception message is: The current build operation (build key Build Key[UnityConsole.NullLogger, null]) failed: The parameter v could not be resolved when attempting to call constructor UnityConsole.NullLogger(System.String v). (Strategy type BuildPlanStrategy, index 3)"}

Why doesn't unity look into named instances? To get it to work, I'll have to do:

ILogger nullLogger = container.Resolve<ILogger>("NullLogger");

Where is this behavior documented?

Arun

May 5, 2010 at 8:29 AM

Why are you assuming that the container would go looking for something other than the name you asked for? The unnamed registration is the unnamed registration, a named registration is a named registration. Period. Are we just supposed to guess?

I believe this behavior IS documented. It may not be extremely explicit.

 

May 5, 2010 at 8:52 AM

If that's true, then when you do:

container.RegisterType<ILogger, NullLogger>();
ILogger nullLogger = container.Resolve<ILogger>();

I get an instance of NullLogger (even though it is named). (I just tested this).

And once again, the above code does not work when there's a constructor injection on the type. Seems like you are quite sure of the behavior being documented. I request the link and thanks for your input.

Arun

May 5, 2010 at 9:27 AM

I got my concerns resolved. The explanation is here:

http://stackoverflow.com/questions/2771217/named-type-not-used-for-constructor-injection

Arun