Dependency injection is one way to implement inversion of control.To understand dependency injection please refer Dependency Injection in .NET .So assuming you understand the basics of Dependency Injection now we will implement Dependency Injection using Unity container.
Dependency injection injects the dependencies of a class at runtime.This creates a loose coupling between the classes as changes in one class does not impact the other dependent classes
DI Containers: to automatically inject dependencies we use a Dependency Injection(DI) container.We can also inject the dependencies manually but using a DI container provides the following benefits
Automatic Dependency Resolution When dependendencies are managed by the container there are less chances of error.Suppose if our application has a lot of dependencies then injecting those dependencies is also difficult to manage if we are injecting them without a DI container.
Decouples the client from the dependency If the client is directly injecting the dependency then client code is aware of the class dependencies.This tight coupling can be a problem if tomorrow the dependencies of the class changes.
Suppose if a X has a dependency on Y then without the container it is the responsibility of the client to create and inject the instance of class Y.
There are few popular .NET dependency injection containers such as:
- Castle Windsor
- StructureMap
- Autofac
- Unity
- Ninject
In the following example we will be using Unity to manage the dependencies.It has a simple API and is also easy to configure.Unity as a dependency injection container is mostly used in .NET application.
We have the following Employee class which takes IDBAccess as a constructor dependency.To create loosely coupled architecture using dependency injection we use an interface
which removes the direct dependencies between the classes.So we use IDBAccess parameter in the Employee class constructor
class Employee { public string Name { get; set; } IDBAccess _DBAccess; public Employee(IDBAccess DBAccess) { _DBAccess=DBAccess; } }
Dependency Injection using Unity container
Adding Unity in our application
To implement the dependency injection using the Unity DI container we add the Nuget package for Unity which adds the required references to the project.We add the unity dependency injection container in our application by adding a reference to the Unity DI nuget package.
Adding the Unity Dependency Injection container package adds the following references to the project:
Following references are added to the project
Microsoft.Practices.Unity and Microsoft.Practices.Unity.RegistrationByConvention Main assemblies which implements Dependency Injection functionality
Microsoft.Practices.Unity.Configuration We can register the dependencies in a xml file and also in the code.This assembly is useful when we register the dependencies in xml file.
Using the Unity Dependency Injection container
We register the objects in container and retrieve the objects from the container,so it is the container with which our client directly interacts.
There are two main steps to use Unity DI container in our application.
Register the dependencies We register dependencies using the RegisterType method.It is a generic method in which provide the mapping between the interface type or the abstract class and the concrete type which needs to be instantiated when an object of the interface type is requested by the client.First we instantiate the container.Once we have the container object we use the ResgisterType<Interface,ConcreteType>() method to add the mapping between the interface and the Concrete types.
var container = new UnityContainer(); container.RegisterType<IDBAccess, SQLDataAccess>();
The above dependency adds a mapping between the IDBAccess and SQLDataAccess types.This means that whenever a dependency of type IDBAccess is required an instance of SQLDataAccess is created and is injected into the dependent type.
Resolve the dependencies To create the object which takes a dependency using the constructor or property injection we use the resolve method.When we use the resolve method the necessary dependencies are automatically injected.So we are not concerned with providing the dependencies ourselves.We can get an object of Employee class using the Resolve() method as:
Employee employee = container.Resolve<Employee>();
The above call to the Resolve() method will automatically inject the required dependencies in the Employee class.Since the Employee class depends on the IDBAccess interface and we have registered the mapping between the IDBAccess interface and the SQLDataAccess class ,an object of SQLDataAccess is automatically created by the container and is passed to the Employee class constructor.
namespace DIContainer { class Employee { public string Name { get; set; } IDBAccess _DBAccess; public Employee(IDBAccess DBAccess) { _DBAccess=DBAccess; } } interface IDBAccess { string connection { get; set; } } class SQLDataAccess:IDBAccess { public string _connection; public string connection { get { return "test connection"; } set { _connection=value; } } } class Program { static void Main(string[] args) { var container = new UnityContainer(); container.RegisterType<IDBAccess, SQLDataAccess>(); Employee emp = container.Resolve<Employee>(); } } }
Property Injection
To implement property injection we need to apply the [Dependency] attribute to the property in the class.
Suppose we have a class employee which exposes a property PersonalDetails then we can use the property injection as:
public class Employee { private personalDetails [Dependency] public PersonalDetails PersonalDetails { get { return personalDetails; } set { supplier = personalDetails; } } }
Now when we create the Employee object using the Unity container,the PersonalDetails object is automatically created and is assigned to the PersonalDetails property.
It is important to keep all the type registrations together .If we keep the type registrations together then we can manage the registrations from a single location in our code.We add the registrations to the Unity container at the application startup so that the types are available later on in the application life cycle.In the case of web applications this means registering the types in the container in the global.asax while for console applications we can register the dependencies in the Main() method.
Registering the dependencies in configuration file
Though registering the types with the container in the code is better approach since it allows to easily catch the errors.But it also means recompiling the code.Another approach for registering the types in the Unity container is using the configuration file.If we use the configuration file then we can easily change the registrations without recompiling the code.
Following is a sample XML configuration file which registers the dependencies in the unity container.We are registering the same types which we have registered in the code above.
<?xml version="1.0" encoding="utf-8"?> <unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/> </configSections> <typeAliases> <typeAlias alias="IDBAccess" type="DIContainer.IBook,DIContainer" /> <typeAlias alias="SQLDataAccess" type="DIContainer.IBook,DIContainer" /> </typeAliases> <container> <register type="IDBAccess" mapTo="SQLDataAccess" /> </container> </unity>
We can configure the Unity container as:
var container = new UnityContainer(); var section =(UnityConfigurationSection)ConfigurationManager.GetSection("unity"); section.Containers.Default.Configure(container);
By implementing Dependency Injection using Unity container we can easily register the dependencies ,in our application, in the Unity container at application startup.We can ask the Unity container to create objects for us and it will automatically resolve the dependencies.This is more useful when we have a complex application in which it is difficult for us to manage the dependencies between the types ourselves.