jgauffin
jgauffin

Reputation: 101150

Unity and constructors

Is it possible to make unity try all defined constructors starting with the one with most arguments down to the least specific one (the default constructor)?

Edit

What I mean:

foreach (var constructor in concrete.GetConstructorsOrderByParameterCount())
{
   if(CanFulfilDependencies(constructor))
   {
       UseConstructor(constructor);
       break;
   }
}

I don't want Unity to only try the constructor with most parameters. I want it to continue trying until it finds a suitable constructor. If Unity doesn't provide this behavior by default, is it possible to create an extension or something to be able to do this?

Edit 2

I got a class with two constructors:

public class MyConcrete : ISomeInterface
{
    public MyConcrete (IDepend1 dep, IDepend2 dep2)
    {}

    public MyConcrete(IDepend1 dep)
    {}
}

The class exists in a library which is used by multiple projects. In this project I want to use second constructor. But Unity stops since it can't fulfill the dependencies by the first constructor. And I do not want to change the class since the first constructor is used by DI in other projects.

Hence the need for Unity to try resolving all constructors.

Upvotes: 2

Views: 3884

Answers (1)

Aaron McIver
Aaron McIver

Reputation: 24713

Unity will choose the constructor with the most parameters unless you explicitly tag a constructor with the [InjectionConstructor] attribute which would then define the constructor for Unity to use.

When you state a suitable constructor; that is somewhat contingent on the environment. If for instance you always want to guarantee that a certain constructor is used when making use of Unity use the attribute mentioned previously, otherwise explicitly call the constructor you want to use.

What would be the point of Unity "trying" all constructors? It's purpose is to provide an instance of a type in a decoupled manner. Why would it iterate through the constructors if any constructor will create an instance of the type?

EDIT:

You could allow the constructor with the most params to be used within the project that does not have a reference to that type within its container by making use of a child container. This will not force the use of the constructor with a single param but it will allow the constructor with 2 params to work across the projects now.

You could also switch to using the single constructor across the board and force the other interface in via another form of DI (Property Injection), not Constructor Injection...therefore the base is applicable across the projects which would make more sense.

Upvotes: 3

Related Questions