Unity Container: Constructor Injection

In the previous chapter, we learned about registering and resolving types using unity. Here, you will learn how unity container performs constructor injection.

Construction injection is a type of Dependency Injection where dependencies are provided through a constructor. Visit Dependency Injection chapter to learn more about it.

We learned about Resolve() method in the previous chapter. By default, Resolve<T>() performs construction injection to inject dependencies and returns an object of specified type. Let's take the same examples from the previous chapter.

public interface ICar
{
    int Run();
}

public class BMW : ICar
{
    private int _miles = 0;

    public int Run()
    {
        return ++_miles;
    }
}

public class Ford : ICar
{
    private int _miles = 0;
    public int Run()
    {
        return ++_miles;
    }
}

public class Audi : ICar
{
    private int _miles = 0;

    public int Run()
    {
        return ++_miles;
    }

}
public class Driver
{
    private ICar _car = null;

    public Driver(ICar car)
    {
        _car = car;
    }

    public void RunCar()
    {
        Console.WriteLine("Running {0} - {1} mile ", _car.GetType().Name, _car.Run());
    }
}

As you can see above, the Driver class accepts an object of type ICar in the constructor. So, the unity container will inject dependencies via constructor as shown below.

Example: Construction Injection using Unity Container
var container = new UnityContainer();
container.RegisterType<ICar, BMW>();

var driver = container.Resolve<Driver>();
driver.RunCar();
Output:
Running BMW - 1 mile

In the above example, container.RegisterType<ICar, BMW>() maps ICar to BMW. It means whenever unity container needs to inject an object of type ICar, it will create and inject an object of BMW class. The container.Resolve<driver>() method will create and return an object of Driver class by passing an object of ICar into the constructor. As we mapped ICar to BMW, it will create and inject BMW object to a constructor of Driver class and return an object of Driver class.

Thus, the Resolve() method by default performs constructor injection while resolving types.

Multiple Parameters

You can also inject multiple parameters in the constructor. Consider the following example.

public interface ICarKey { 
        
}

public class BMWKey : ICarKey 
{

}

public class AudiKey : ICarKey 
{

}

public class FordKey : ICarKey 
{

}

public class Driver
{
    private ICar _car = null;
    private ICarKey _key = null;

    public Driver(ICar car, ICarKey key) 
    {
        _car = car;
        _key = key;
    }

    public void RunCar()
    {
        Console.WriteLine("Running {0} with {1} - {2} mile ", _car.GetType().Name , _key.GetType().Name,  _car.Run());
    }
}

So now, you can register ICar and ICarKey with unity and inject both the parameters as shown below.

Example: Constructor Injection for Multiple Parameters
var container = new UnityContainer();
            
container.RegisterType<ICar, Audi>();
container.RegisterType<ICarKey, AudiKey>();

var driver = container.Resolve<Driver>();
driver.RunCar();
Output:
Running Audi with AudiKey - 1 mile

Multiple Constructors

If a class includes multiple constructors then use [InjectionConstructor] attribute to indicate which constructor to use for construction injection.

public class Driver
{
    private ICar _car = null;
       
    [InjectionConstructor]
    public Driver(ICar car)
    {
        _car = car;
    }
    
    public Driver(string name)
    {
    }
    
    public void RunCar()
    {
        Console.WriteLine("Running {0} - {1} mile ", _car.GetType().Name, _car.Run());
    }
}

As you can see, Driver class includes two constructors. So, we have used [InjectionConstructor] attribute to indicate which constructor to call when resolving the Driver class.

You can configure the same thing as above at run time instead of applying [InjectionConstructor] attribute by passing InjectionConstructor in the RegisterType() method as shown below.


container.RegisterType<Driver>(new InjectionConstructor(new Ford()));

//or 

container.RegisterType<ICar, Ford>();
container.RegisterType<Driver>(new InjectionConstructor(container.Resolve<ICar>()));

Primitive Type Parameter

Unity also injects primitive type parameter in the constructor. Consider the following Driver class with primitive type parameter in the constructor.

public class Driver
{
    private ICar _car = null;
    private string _name = string.Empty;

    public Driver(ICar car, string driverName)
    {
        _car = car;
        _name = driverName;
    }

    public void RunCar()
    {
        Console.WriteLine("{0} is running {1} - {2} mile ", 
                        _name, _car.GetType().Name, _car.Run());
    }
} 

Use InjectionConstructor class to configure constructor's parameters values. Pass an object of InjectionConstructor class in the RegisterType() method to specify a multiple parameters values.

Note : InjectionConstructor is derived from InjectionMember Class. The InjectionMember is an abstract class which can be used to configure injection type. There are three subclasses of InjectionMember: InjectionConstruction to configure construction injection, InjectionProperty to configure property injection and InjectionMethod to configure method injection.
var container = new UnityContainer();
            
container.RegisterType<Driver>(new InjectionConstructor(new object[] { new Audi(), "Steve" }));

var driver = container.Resolve<Driver>(); // Injects Audi and Steve
driver.RunCar();
Output:
Steve is running Audi - 1 mile