Introduction
DI (Dependency Injection) or IoC (Inversion of control) is basically used to manage dependency in our applications. Both the terms DI and IOC will denote the same things it is basically used for creating dependency and inject whenever it is required. This is very helpful when we are going to make things tightly coupled to loosely coupled. There are many IOC containers available but the Unity, Ninject and Autofac are the three most common and popular containers that are used in .NET.
Each DI has its own pros and cons. In this article, I am going to demonstrate the implementation of all three dependency injections in .NET with an example. It will really give you the idea as to which one is the best to choose during application development.
Unity
Unity IOC container was released by Microsoft. It facilitates building loosely-coupled applications and provides developers with the following advantages:
- Simplified object creation
- Abstraction of requirement
- Consistent API
- Good documentation
It is also very helpful when we're used to any application so it has pluggable facility so there is no need of configuration change during application development. So here I am giving you the small POC which is basically the console project. First of all, download unity package from nuget package manager.
When your package successfully installs, then you will see the three references in your project for unity.
In this implementation, we basically create a student
class and a University
class. Display result of Student
class basically used internally University
class or you can say that it is dependent on University
class. So here, we are going to create dependency by Unity. There are three ways by which you can inject the dependency, by constructor, by property and by method.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using Microsoft.Practices.Unity;
namespace ExamManagementByUnity
{
public interface IStudent
{
}
public class Student : IStudent
{
private IUniversity _University;
[Dependency]
public IUniversity University
{
get { return _University; }
set { _University = value; }
}
public void DisplayResult()
{
_University.ShowResult();
}
}
public interface IUniversity
{
void ShowResult();
}
class University : IUniversity
{
public void ShowResult()
{
Console.WriteLine("You got first division in Engineering program.");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Unity;
namespace ExamManagementByUnity
{
class Program
{
static void Main(string[] args)
{
IUnityContainer unitycontainer = new UnityContainer();
unitycontainer.RegisterType<IUniversity, University>();
Student stu = unitycontainer.Resolve<Student>();
stu.DisplayResult();
Console.ReadLine();
}
}
}
Let's start with main()
function. Basically, the below line will give the object of IUnityContainer
.
IUnityContainer unitycontainer = new UnityContainer();
Then we will register the class on which the main class is dependent. In our example, we said that the Student
class is dependent on the University
class. So we need to add the University
class to the container.
unitycontainer.RegisterType<IUniversity, University>();
Now the container is ready for use to solve dependency of other classes. We will now create one object of the Student
class and solve its dependency using IoC container as in the following:
Student stu = unitycontainer.Resolve<Student>();
Here, you can see that we create the object of University
class and send this to the container and all things are handled by the container. The above university
class also has two other DI by constructor and by method. Now you can see the output in console.
In this above program, we have learned how to implement an IoC container using Unity that is very simple and flexible to use with pluggable approach.
Ninject
Ninject is the newly dependency injection framework for .NET applications. It is now available in stable version. It is very useful when you developing any component which is re-utilized in all different systems. Ninject has the below advantages which made it very popular among all the DIs.
- Easy to learn API
- Light-weight (122 KB, version-3.0.015)
- Second-generation DI Container
- Faster because of lightweight code generation
It will provide extensions when you used it in WCF and MVC applications. So again, the below example is a console application which will demonstrate how Ninject is easy to use.
Download Ninject from nuget package manager.
After successfully installation of package, you will see the added reference in the console project:
The below code snippet basically demonstrates the console application for Ninject dependency injection.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
namespace DependencyResolvedByNinject
{
public interface IVehicle
{
void Owns();
}
class Vehicle : IVehicle
{
public void Owns()
{
Console.WriteLine("I Owns a Car.");
}
}
public class Mohan
{
IVehicle ObjVehicle = null;
public Mohan(IVehicle tmpVehicle)
{
this.ObjVehicle = tmpVehicle;
}
public void Drive()
{
this.ObjVehicle.Owns();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
namespace DependencyResolvedByNinject
{
class Program
{
static void Main(string[] args)
{
Ninject.IKernel kernal = new StandardKernel();
kernal.Bind<IVehicle>().To<Vehicle>();
var instance = kernal.Get<Mohan>();
instance.Drive();
Console.ReadLine();
}
}
}
The IVehicle interface
and Vehicle class
are very straight forward, we have just defined the Owns()
function in the IVehicle interface
and we have implemented it in the Vehicle class
.
Now, in the "Mohan
" class (the class name is purposefully given, since I wanted to use the class as Vechicle
).
To make the class de-coupled, we have implemented function injection. The Drive()
function will call the Own()
function internally, that has been defined within the Vehicle
class.
Let's start with main
function. The below line will create the kernal class. The Kernel is all and all of Ninject.
Ninject.IKernel kernal = new StandardKernel();
In the below line, we bind the interface with the appropriate class:
kernal.Bind<IVehicle>().To<Vehicle>();
In the below two lines, we are solving the dependency of Vehicle
class over the Mohan
class and then, we are calling the Drive()
function.
var instance = kernal.Get<Mohan>();
instance.Drive();
We execute the Drive()
function in the Mohan
class where the Mohan
class is dependent on the Vehicle
class without creating an object of the Vehicle
class.
We have bound the Vehicle
class associated with IVehicle interface
to the IoC container and the IoC container has taken care of rest of the things. The console output shows the below message:
Autofac
There are many IoC containers in the market, Autofac is one of them. For making our architecture de-coupled, we have to use any of the IOC containers. Below is the example of the autofac Ioc container. In this, we are going to demonstrate the injection of dependency by constructor and by property. This is open source and developed in Google code which has the following advantages:
- Commercial support available
- Easy to learn API
Download the nuget package for autofac and install in your application.
Now the reference is visible in your project when nuget package manager installs the package successfully.
I am creating the two interfaces with the concrete classes with method definition QueueService
is the class where we are going to inject the dependency by constructor and by property.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autofac;
namespace QueueServiceByAutofac
{
public interface IPushServive
{
void Execute();
}
public class PushServive : IPushServive
{
public void Execute()
{
Console.WriteLine("An item is pushed in to the Queue.");
}
}
public interface IPopService
{
void Execute();
}
public class PopService : IPopService
{
public void Execute()
{
Console.WriteLine("An item is pop out in to the Queue.");
}
}
class QueueService
{
public IPushServive ObjPushSerivce = null;
public IPopService ObjPopService = null;
public QueueService(IPushServive tmpService)
{
ObjPushSerivce = tmpService;
}
public IPopService SetPopService
{
set { ObjPopService = value; }
}
public void Process()
{
ObjPushSerivce.Execute();
ObjPopService.Execute();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autofac;
namespace QueueServiceByAutofac
{
class Program
{
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<PushServive>().As<IPushServive>();
builder.RegisterType<PopService>().As<IPopService>();
var container = builder.Build();
container.Resolve<IPushServive>().Execute();
container.Resolve<IPopService>().Execute();
Console.ReadLine();
}
}
}
We have then implemented a QueueService
class that is dependent on both PushService
and PopService
.The console output is as below:
So the above examples demonstrate how you can play with the DI and these are really facilitating you while you want to choose Ioc container during application development. So the final choice is yours regarding what you want to use. The code base DependencyInjections.zip as POC is attached with this article.
History
- 3rd December, 2015: Initial version