views:

542

answers:

4

I'm using the Unity IoC container for resolving my objects. However, I've run into an issue. When I have more than one constructor - how does Unity know which one to use? It seems to use the one with parameters when I have one with and one without. Can I explicitly tell it which constructor to use?

Specifically I had a case similar to the following Person class with two constructors. In this case I want the IoC container to use the default constructor - without parameters - but it chooses the one with parameters.

public class SomeValueObject
{
    public SomeValueObject(string name)
    {
        Name = name; 
    }
    public string Name { get; set; }
}

public class Person
{
    private string _name; 

    public Person()
    {
        _name = string.Empty;
    }

    public Person(SomeValueObject obj)
    {
        _name = obj.Name;
    }
}

This obviously fails as it can't create the SomeValueObject - not knowing what to inject to its string parameter. The error it gives is:

Resolution of the dependency failed, type = "MyApp.Person", name = "". Exception message is: The current build operation (build key Build Key[MyApp.Person, null]) failed: The parameter obj could not be resolved when attempting to call constructor MyApp.Person(MyApp.SomeValueObject obj). (Strategy type BuildPlanStrategy, index 3)

The container registration:

Container.RegisterType<Person, Person>(new Microsoft.Practices.Unity.ContainerControlledLifetimeManager());

And the resolving:

var person = Container.Resolve<Person>();
+1  A: 

Multiple-Constructor Injection Using an Attribute

When a target class contains more than one constructor with the same number of parameters, you must apply the InjectionConstructor attribute to the constructor that the Unity container will use to indicate which constructor the container should use. As with automatic constructor injection, you can specify the constructor parameters as a concrete type, or you can specify an interface or base class for which the Unity container contains a registered mapping.

Diadistis
+2  A: 

By default, Unity chooses a constructor with maximum number of arguments. To override this, decorate required constructor with InjectionConstructorAttribute.

Anton Gogolev
+3  A: 

Register it like this instead:

container.RegisterType<Person>(new InjectionConstructor());

You can add the LifetimeManager as well using an overload of the RegisterType method.

That said, when modeling for DI, your life will be much easier if you have unambiguous contructors (i.e. no overloaded constructors).

Mark Seemann
Thx. I've been using the IoC container for a while, and this is the first time I've seen the need of overloaded constructors, so I'm all with you there.. (btw; out of votes today, so +1 tomorrow!)
stiank81
A: 

I really have to point out the way you're using dependency injection in this instance is just wrong. The container should be able to inject SomeValueObject on the construction.

What you most likely should do is register a default object of SomeValueObject that the .Name property returns string.Empty instead.

Chris Marisic
Maybe my simple example is a bit off, but imo there is a need of two different constructors in the actual code.. Thanks for mentioning anyway.
stiank81