Specify constructor for the Unity IoC container to use

22,740

Solution 1

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).

Solution 2

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

Solution 3

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.

Share:
22,740

Related videos on Youtube

stiank81
Author by

stiank81

System Developer mainly living in the .Net-world. Coding in C#, Javascript, html, css, ..

Updated on March 26, 2020

Comments

  • stiank81
    stiank81 over 4 years

    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>();
    
    • Martin
      Martin over 14 years
      Isn't the point of IoC to use Interfaces ???
    • stiank81
      stiank81 over 14 years
      Sure, and I do that mostly. But this didn't make a difference for the question.
    • Luke Puplett
      Luke Puplett over 8 years
      @Martin Many programmers use classes and avoid the fake generality of making an interface and then only having one implementation of it. It also avoids the masses of smelly IoC wire-up you see in most enterprise apps, but still lets you switch-out some implementations when the need arises. programmers.stackexchange.com/questions/133471/…
  • stiank81
    stiank81 over 14 years
    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.
  • Casey
    Casey over 10 years
    What if you haven't written it?
  • Casey
    Casey over 10 years
    Which overload are you referencing?
  • granadaCoder
    granadaCoder over 8 years
    @Casey...I believe the empty constructor.
  • Sean B
    Sean B over 8 years
    We should mention that decorating the constructor couples the component to Unity as its IoC container. Handling the specification during registration is probably preferable so that components don't need to take a reference to Unity and so a different IoC could be swapped out if desired.
  • granadaCoder
    granadaCoder almost 8 years
    Since there are no arguments for InjectionConstructor, it is calling the empty constructor of Person. If the code had been 'new InjectionConstructor(new SomeValueObject("John Smith"))', that would have called the (other) Person constructor, where the "other" constructor is the one which uses the SomeValueObject object/argument.
  • Seafish
    Seafish over 6 years
    You can also do new InjectionConstructor(typeof(IMyDependency), typeof(IMySecondDependency)) to specify a constructor with dependencies if you don't want to pass in a manual object for your class's dependencies but instead you want Unity to inject your already registered types
  • BrainSlugs83
    BrainSlugs83 almost 6 years
    Looks like you don't even have to do that. You can just put the Unity.Attributes.InjectionConstructorAttribute on your constructor! -- Thanks for pointing me in the right direction! :)
  • royalTS
    royalTS over 2 years
    "By default, Unity chooses a constructor with maximum number of arguments", but only if all required values are known to Unity. In my case, I missed to register one type and Unity felt back to a parameterless constructor.