IOC is mechanism by which we can add abstraction between
dependencies to make them loosely coupled code.
Abstraction is added through interface.
Now lets understand this by example.
Before Implementing IOC:
I have a class called "Black_And_White_Printer" which has one print() method. Print() method will print in black and white. I also have consumer class which is dependent on Black_And_White_Printer class.
public class consumer
{
public void DoWork()
{
Black_and_White_Printer obj = new Black_and_White_Printer();
obj.print();
}
}
Notice: Consumer class is tightly coupled with Black_And_White_Printer class.
Now let say after few months of this implementation management comes up with ColourFull_Printer and now they want Colour print rather than black and white.
public class consumer
{
public void DoWork()
{
ColourFull_Printer obj = new ColourFull_Printer();
obj.print();
}
}
Notice: Because our Consumer class is tightly coupled with Black_And_White_Printer class, we now have to change consumer class on changing the method of print. In other words our consumer class is dependent on mechanism of print and that is reason we have to change every single time.
Understanding Problem without IOC:
- Tightly coupled code. i.e. Consumer is tightly dependent on Printing mechanism.
- Requires more maintenance. i.e. Whenever printing mechanism change we have to change our consumer class.
- Not good for writing unit test cases.
Now, lets perform IOC on above code. Again: IOC is mechanism by which we can add abstraction between dependencies to make them loosely coupled code. Abstraction is added through interface.
so In order to remove dependency betweeen consumer class and printing mechanism add an layer of abstraction using interface.
public interface IPrinter
{
void print();
}
public class Black_And_White_Printer :
IPrinter
{
public void print()
{
Console.WriteLine("Black and
White Print");
}
}
public class ColourFull_Printer : IPrinter
{
public void print()
{
Console.WriteLine("Colourfull
Print");
}
}
public class consumer
{
IPrinter printer;
public consumer(IPrinter printer)
{
this.printer = printer;
}
public void DoWork()
{
printer.print();
}
}
In above code: We first added interface name IPrinter which contains print() method. Now each printing mechanism is required to implement IPrinter interface. That is our case both Black_And_White_Printer class and ColurFull_Printer class has to implement IPrinter.
Now notice inside consumer class we introduce Constructor Dependency Injection method to perform IOC.
Advantage after implementing IOC:
- Loosely coupled code. i.e. Consumer is no more depended on Printing mechanism.
- Requires less maintenance. i.e. Whenever printing mechanism change we are not required to change our consumer class.
- Good for writing unit test cases.
Dependency Injection Example
Dependency Injection is mechanism by which we can inject dependency into component. Considering our above example concept now I will show how can we perform Dependency Injection using Unity Framework.
As per above code create a console application and add files along with code as mentioned above.
- Interface: IPrinter
- Class: Black_And_White_Printer
- Class: ColourFull_Printer
- Class: Consumer
Also add nuget package: Unity container
After its installation it will add folder App_Start and 2 files.
Now open UnityConfig.cs. We should be maintain all dependencies in this files.
For this example: Inside method RegisterTypes()
Replace following line:
// container.RegisterType<iproductrepository, productrepository>();
With
container.RegisterType<iprinter, black_and_white_printer>();
Now open Program.cs
using DependencyInjectionExample.App_Start;
using Microsoft.Practices.Unity;
class Program
{
static void Main(string[] args)
{
//Start the Unity Container
UnityWebActivator.Start();
var ioc = UnityConfig.GetConfiguredContainer();
//Create instance of consumer class
var client = ioc.Resolve<consumer>();
Note: Above code is displaying "Black and White Print" because inside UnityConfig.cs our IPrinter interface is pointing to Black_And_White_Printer class.
Now let say we want to display colurfull print then all we have to do is change the UnityConfig.cs file to following: