Thursday 24 April 2014

Loose Coupling Mechanism - Dependency Injection with C#

Hi programmers! I am back again. My previous blogs were typically on open-source technologies. In this blog, I am back with my 'old-school' thing, C#

C# has always been a favorite language for me. I have been using this language for last few years (even my B.Tech final year project was developed with it), and have used almost every modern C# tools.

In this blog, as the title says, I will discuss about a programming design pattern called 'Dependency Injection'. Let me go into a bit details.



Dependency Injection and Loose Coupling - the basics

Consider yourself as a business-man. You have several accounts in different banks, you need to transfer money to different persons or companies each day. And, you handle everything by yourself. 

Suppose, for personal transactions you use a particular bank account. Now, due to some problems ( the bank provides a very bad web interface, suppose! ) you have decided to use an another account for those transactions. This decision may mess you up. Now, every time you transfer money, you need to remember the new bank account details. And it may happen, that you are still using the old account for some transactions, by mistake. 

Now, consider a scenario, where you have a P.A.(for future references I will consider your P.A. as a lady). She  handles your bank transactions exclusively. She knows what to pay, whom to pay, and from where to pay. You just instruct her if you decide to change anything. 

So, now you will just tell her to use the new account except the old account for personal transactions, she will handle the rest.

This is basically an example of Dependency Injection and Loosely Couple system in real life. 

In Loosely Coupled system, one component, called a 'client',  uses the other component (or components), called a 'Service', of the system having a very little or no knowledge about the used component(s). 

Dependency Injection (DI) is a software design pattern which encourages this Loose Coupling architecture. This pattern passes the 'Service' to the 'Client' , rather than the 'Client' to build or find the service. 

In this DI, we generally make our classes and objects dependent on the interfaces, instead of depending on the Concrete objects  (any object created by a new keyword). This mechanism has several benefits, which I will discuss later.

Without DI technique

First check out the following C# code-snippet : 

public class StudentService
{
public void AddStudent (String name, int roll, int class)
{
    StudentRepository repos= new StudentRepository();
    repos.InsertStudent(name,roll,class);
            LoggerService logger = new LoggerService();
            logger.log("Student with roll-" + roll.ToString() + "                  class- " + class.ToString() + " added");
}
}

Here, we have a class named StudentService  which contains a method to add a student, the AddStudent method. This method takes student name, roll and class and inserts the student into the database.

Now, to do this, we have created an object of an another class StudentRepository (which contains the actual method to insert the student). Then we have called the InsertStudent method using that object. Then we have created an object of the LoggerService class and used that class to log the event. 

So, in this case class StudentService is dependent on two another classes, 

StudentRepository and LoggerService.

Dependency Injections - how to do it?

In our example, we have created two Concrete Objects. So, to achieve a loosely coupled  system with dependency injection, we need to make the StudentService class dependent on interfaces, instead of Concrete objects. 

First, we will build two interfaces for StudentRepository and LoggerService classes respectively. 

interface IStduentRepository
{
  int AddStudent();
}

public class StduentRepository : IStduentRepository
{
  public int AddStudent()
DI technique diagram
  {
     //body of the method
  }  
}

interface ILoggerService
{
  void log();
}


public class LoggerService : ILoggerService
{
  public void log()
  {
     //body of the method
  }  

}

Now we have two interfaces for  StudentRepository and LoggerService classes. Lets see how we can use those in DI technique.

DI technique 1 - Constructor Injection:

In this technique, we pass an object's dependencies to it's constructor. The below cod-snippet implements  this : 


public class StudentService
{
IStudentRepository repos = null;
ILoggerService logger = null;
public StudentService(IStudentRepository repos, ILoggerService logger)
{
   if (repos == null || logger)
       throw new Exception ("Parameters can not be null");
this.repos = repos;
this.logger = logger;
}
public void AddStudent (String name, int roll, int class)
{

repos.InsertStudent(name,roll,class);

logger.log("Student with roll-" + roll.ToString() + " class- " + class.ToString() +   " added");
}
}

Here, the constructor of the StudentService class accepts two arguments, which are instances of the IStudentRepository and ILoggerService interfaces. If someone passes null as the constructor parameters, then we will throw an exception. All the methods within class can use those instances as needed. So, to call the StudentService class, we need to write : 

StudentService service = new StudentService (new StudentRepository(), new LoggerService());

Hence, the StudentService class does not have any Concrete objects, and it depends on interfaces which are injected into the class using Dependency Injection mechanism.

DI technique 2 - Setter Injection:

Instead of passing dependencies as constructor parameters, in setter injection technique we take the dependencies using public property fields, which are exposed by the object in need.

We have two advantages of using this technique over Constructor Injection. 

  1. We can create the expensive resources and services as let as possible, actually when we need those.
  2. We do not need to the modify the constructor definition of a legacy class.
We can implement the Setter Injection with our example as follows : 


public class StudentService

{

IStudentRepository repos = null;

ILoggerService logger = null;
public IStudentRepository studentRepository {
set { repos = value; }
get {
if (repos == null)
 throw new MemberAccessException("studentRepository" + 
" has not been initialized");
return repos;
}
}
public ILoggerService loggerService {
set { logger = value; }
get {
if (logger == null)
 throw new MemberAccessException("loggerService" + 
" has not been initialized");
return logger;
}
}
public void AddStudent (String name, int roll, int class)
{
studentRepository.InsertStudent(name,roll,class); 
 loggerService.log("Student with roll-" + roll.ToString() + " class- " + class.ToString() + " added");
}
}


In the above example, the constructor accepts no arguments. Instead, the invoking object is responsible for setting the IStudentRepository and ILoggerService dependencies through the newly added properties studentRepository and loggerService before the method AddStudent is invoked.

The value passed to the studentRepository property sets the 'repos' class variable, and if someone tries to get the property without setting it before (the 'repos' variable would be null then), it throws an exception. The loggerService does the same thing for the 'logger' class variable. So, whenever someone invokes the AddStudent method, the method calls the properties, and does the task if both of the variables are set, otherwise rises an exception.


Dependency Injections - why we use it?

Now you know how to implement Loose Coupling with Dependency Injection. But why we need it? Why we need to make a program much more complex?? Lets discuss the reasons.


The first and most important reason is mocking. Mocking is an important part of Unit testing. An object under test may have dependencies on other complex objects. To isolate the behavior of the object we want to test, we replace the other objects by mocks that simulate the behavior of the real objects. So, in our scenario, to test the StudentService class, we may need to mock the StudentRepository and LoggerService classes. The following code-snippet shows the mocking technique applied to mock the LoggerService class : 

public class FakeLoggerService : ILoggerService
{
  public void log()
  {
     //body of the fake/mocked method
  }  

}
StudentService service = new StudentService (new StudentRepository(), new FakeLoggerService());

So, in Unit testing, we can use mocking to mock the whole Data-access layer to eliminate unnecessary  database calls while testing the Business Logic layer with dummy data.

In real-life scenarios, a tool called Nmock is used for mocking. To know more, visit this Wikipedia page. 

Not only this. DI also helps programmers to arrange the code in a proper way. Suppose, in a project you are responsible for writing the Data-access layer, and your colleague is writing  the Business Logic layer. If you use Dependency Injection in your code, then you can easily write your parts separately without depending on each other. You just need to define your interfaces, and you're done!!  


The Bottom Line -  available tools

To implement DI properly, we need some tools and libraries. The most popular library for C# and .net is Ninject.

www.ninject.org states that :

"Ninject is a lightweight dependency injection framework for .NET applications. It helps you split your application into a collection of loosely-coupled, highly-cohesive pieces, and then glue them back together in a flexible manner. By using Ninject to support your software's architecture, your code will become easier to write, reuse, test, and modify."

We have used ninject in our several projects. It is really easy to use, does exactly what you need.



So, my fellow programmers, try this Dependency Injection technique when you next time use asp.net or C#, and let me know it helped you or not.

Good bye for now. Post your comments and queries below. See you again in my next blog.

Happy programming!





Visit our website | Visit Our LinkedIn Page | Search us on Google








1 comment:

  1. Live Project Training using ASP.Net, c#, MS SQL
    The Keshri Software Solutions is a one-stop site for Asp(.)Net Live Project Training. We have successfully completed several batches and all are placed and working in a reputed company.
    Our aim is to provide crystal clear concepts and to boost programming & technology skills of candidates through best Live Project Training.
    Features:
    • It's a fully practical training program
    • Best in Industry Asp(.)Net Live project Training
    • Live Project under Senior Programmer guidance
    • Best IT office Environment.
    • It's a full time training ,Office time 10:30AM- 7:30 PM
    • 100% Job Assistance
    • Beneficial for BE/BTECH/MCA students and those who are looking for job?

    Trainer Profile: http://udalbharti.kebhari.com
    Website: training.ksoftware.co.in
    Course details can be downloaded from here
    http://ksoftware.co.in/Training_Outlines.pdf

    ReplyDelete