Unity Container: Property Injection

In the previous chapter, we learned about constructor injection. Here, we will learn about property injection using unity container.

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

Let understand how we can perform property injection using unity container. Consider the following example classes.

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
{
    public Driver()
    {
    }

    [Dependency]
    public ICar Car { get; set; }

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

As you can see in the above sample classes, the Driver class is dependent on a property of type ICar. So, we need to set an object of a class that implements ICar to the Car property using unity container.

Property injection in unity container can be implemented in two ways:

  1. Using [Dependency] attribute
  2. Run-time configuration

[Dependency] Attribute

For the property injection, we first tell the unity container which property to inject. So, we need to decorate the dependent properties with the [Dependency] attribute as shown in the following Driver class.

Example: Apply [Dependency] Attribute
public class Driver
{

    public Driver() 
    {
    }

    [Dependency]
    public ICar Car { get; set; }

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

Now, we can register ICar type and resolve it as shown below.

Example: Property Injection using Unity Container
var container = new UnityContainer();
container.RegisterType<ICar, BMW>();
            
var driver = container.Resolve<Driver>();
driver.RunCar();
Output:
Running BMW - 1 mile

Named Mapping

We can specify a name in the [Dependency("name")] attribute, which can then be used to set property value.

public class Driver
{
    public Driver() 
    {
    }

    [Dependency("LuxuryCar")]
    public ICar Car { get; set; }

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

So now, we can resolve it as below.

Example: Property Injection using Unity Container
var container = new UnityContainer();
container.RegisterType<ICar, BMW>();
container.RegisterType<ICar, Audi>("LuxuryCar");
            
var driver = container.Resolve<Driver>();
driver.RunCar();
Output:
Running Audi - 1 mile

Run-time Configuration

Unity container allows us to configure a property injection with RegisterType() method if a method is not marked with [Dependency] attribute. Pass an object of InjectionProperty class in the RegisterType() method to specify a property name and parameter value.

Note : InjectionProperty is derived from InjectionMember Class. The InjectionMember is an abstract class which can be used to configure injection type. There are three subclasses of InjectionMembers: InjectionConstruction to configure construction injection, InjectionProperty to configure property injection and InjectionMethod to configure method injection.
var container = new UnityContainer();
            
//run-time configuration
container.RegisterType<Driver>(new InjectionProperty("Car", new BMW()));

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

As you can see in the above example, container.RegisterType<driver>(new InjectionProperty("Car", new BMW())) registers Driver class by passing an object of InjectionProperty that specifies the property name "Car" and the BMW object as a value. So, unity container will set an object of BMW to the Car property when we resolve it using container.Resolve<Driver>().