Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • Dependency Injection in .Net

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 315
    Comment on it

    Hi Friends,

          
    Today I will brief you about Dependency Injection. In this blog I will cover up the following topics :-

    1. About Dependency Injection

    2. Real Life Scenario of Dependency.

    3. Benefits of DI.

    4. Tightly Coupled Code.

    5. Loosely Coupled Code(Using Unity Application Block).

    6. Conclusion

     

    1. About Dependency Injection :

    We are talking about the dependency injection as the name justify Injecting The Dependency.

    According to Mark Semann's book on Dependency Injection defination is “Dependency Injection is a set of software design principles and patterns that enable us to develop loosely coupled code.

    We can say that main goal of dependency injection is to decouple the code. So that it will be easy to maintain.

    One interesting thing, I just found it from stackoverflow that how you going to explain dependency injection to a 5 years old child. If he/she asks you. Here the defination:

     

    When you go and get things out of the refrigerator for yourself,you can cause problems. You might leave the door open, you might get something Mommy or Daddy doesn’t want you to have. You might even be looking for something we don’t even have or which has expired.

     

    What this means in terms of object-oriented software development is this: collaborating classes (the five-year-olds) should rely on the infrastructure (the parents) to provide the necessary services.

    DI help us to remove the tightly coupled code from our application. But first thing comes in the mind that what is meant by Tighly Coupled Code. I will provide the tighly coupled code further but first lets have some real life scenario of dependency injection.

     

    2. Real Life Scenario of Dependency Injection

    Consider a case where you need to goto a Beer Bar for drinking beer(Too much alcohol is injurious to health) and you have membership of that particular BAR1. But if one day BAR1 remains closed and you need to go to BAR2 then you will pay there (or purchase the membership of BAR2). Mean you are dependent on BAR1 because you have membership of BAR1. What if you have a Common Membership(Just a Guess) which applicable for all bars in a city. Now you are not dependent on BAR's , only on Common membership card. You have remove your dependency on BAR's and only dependency will be Card you are holding. Below diagram will explain you clearly :

    In technical term You(Class1) is not dependendent on BAR1(Class2). Well you are dependent on the Common Membership Card(Type of Interface). So we remove the dependency directly on classes and we have Inject it using interface(Common Membership Card).

     

    3. Benefits of DI

    Here are some of benefits of dependency injection :

     

    I). Late Binding:

    Suppose you have a application where you are handling database operations using Sql Server. But if requirement changed and you need to use Oracle as a database(too much Changes if we think about the scenario). But dependency injection make it easier to swap out one service with another. I will explain it further with the code.

     

    II). Extensibility

    Decoupled Code can be extended. We can extend with more functionality without affecting extra code.

     

    III). Maintainbility

    Loosely coupled classes are easy to maintain as compared to dependendent code.(or tightly coupled code)

    DI make code loose coupled. And a loosecoupled code is easy to maintain.

     

    IV). Testing

    If code is loosely coupled then it is easy to test. And we can write test cases for each and every class method.

    I am not saying that if you are using dependency injection(to make code loosely), then you don't need to change the code but as compared to tightly coupled code, the chages will be less.

     

    4. Tightly Coupled Code

    In a large application scenario we have three different layers UI(User Interface),BL(Business Logic) and DAL(Data Access Layer). To explain it breief I have used a console application. Below is the tightly coupled code :-

    namespace DependencyInjection
    {
        //UI Layer
        class Program
        {
            static void Main(string[] args)
            {
                Student objStudent = new Student();
                objStudent.SaveStudent();
            }
         }
    
        //BAL Layer
        class Student
        {
            private SqlServerDAL objSqlDal;
    
            //Constructor
            public Student()
            {
                objSqlDal = new SqlServerDAL();
            }
    
            //Method to save student data.
            public void SaveStudent()
            {
                objSqlDal.Save();
            }
        }
    
        //DAL SQL Layer(Here we will implement the sql queries or entity to save the data in table) 
        class SqlServerDAL
        {
            public void Save()
            {
                Console.WriteLine("Save Data Using Sql Server.");
                Console.ReadLine();
            }
        }
    
        //DAL Oracle layer(We will write the queries to save the data in oracle.)
        class OracleDAL
        {
            public void Save()
            {
                Console.WriteLine("Save Data Using Oracle.");
                Console.ReadLine();
            }
        }
    }

    Here we have a Main function and a Student Class with two DAL(SQL and Oracle) classes we will use one at a time. Here we are creating the object of SqlServerDAL in counstructor of Student class. Suppose we need to use Oracle in place of sql server DAL. To use this we need to change the Student class and will create the object of OracleDAL in constructor of Student class as shown below :-

    //To save the oracle data we will create the instance of oracle class DAL. 
    class Student
     {
            private OracleDAL objOracleDal;
    
            public Student()
            {
                //Oracle Instance
                objOracleDal = new OracleDAL(); 
            }
    
            public void SaveStudent()
            {
                //Save function will be called of Oracle
                objOracleDal.Save();
            }
     }

    So to make changes on one layer we need to change the other layer too means it is tightly coupled we need to make it decoupled so that changes to the code will be less and we don't need to make any instances of class. Here I have used some approaches to decouple the code:-

     

    Approach 1:-

    In this approach i have created a Interface and I will inherit this interface in my DAL classes. Now we will create the reference of Interface in Student class as shown in below code :-

    namespace DependencyInjection
       {
        //UI Layer
        class Program
        {
            static void Main(string[] args)
            {
                Student objStudent = new Student();
                objStudent.SaveStudent();
            }
        }
    
        //BAL Layer
        class Student
        {
            //Here we provide a refernce and we will create the instance of Oracle/Sql Constructor
    
            //private SqlServerDAL objSqlDal;
            private IDAL iSqlOracleDal;
            
    	//We can create the instance of Sql or Oracle here 
            public Student()
            {
               //Both Instances of SQL and Oracle.
    
                //iSqlOracleDal = new SqlServerDAL();
                iSqlOracleDal = new OracleDAL();
            }
    
            public void SaveStudent()
            {
                iSqlOracleDal.Save();
            }
        }
    
        //Interface
        public interface IDAL
        {
            void Save();
        }
    
        //DAL SQL Layer
        class SqlServerDAL : IDAL
        {
            public void Save()
            {
                Console.WriteLine("Save Data Using Sql Server.");
                Console.ReadLine();
            }
        }
    
        //DAL Oracle layer
        class OracleDAL : IDAL
        {
            public void Save()
            {
                Console.WriteLine("Save Data Using Oracle.");
                Console.ReadLine();
            }
        }
    }	

    But we have not completely remove the dependency here because we are making instance in the constructor. Lets move on Approach 2.

     

    Approach 2 :-

    In this approach we pass the Interface as a parameter in the constructor as shown in below code :-

    class Student
        {
            //private SqlServerDAL objSqlDal;
            private IDAL iSqlOracleDal;
            
    
            public Student(IDAL _iSqlOracleDal)
            {
                this.iSqlOracleDal = _iSqlOracleDal;
            }
    
            public void SaveStudent()
            {
                iSqlOracleDal.Save();
            }
        }

    But here we need to change in the front end layer as shown below :-

    static void Main(string[] args)
            {
                Student objStudent = new Student(new SqlServerDAL());
                //Student objStudent = new Student(new OracleDAL());
                objStudent.SaveStudent();
            }

    We will pass the objects as shown above, but this is not a good approach as we are making front end dependent by passing the object. So this is tightly coupled code too. We need to make it fully decoupled. We will use third party extensions to make it fully decoupled we have severals third party packages like :-

    Unity,Ninject,Castle Windsor and StrucuctureMap.

    I will explain it using Unity.

     

    5. Loosely Coupled Code(Using Unity Application Block).

    Firstly we need to add reference of Unity in our application. Please follow the following steps :-

    Step 1:-

    Right click on project then click on Manage Nuget Packages. Search for the Unity in the packages and it will show the screen as below:

     

    I have installed it so its showing Uninstall on right side. Install this package it will add 4 references in your application as shown below :-

    Now the code for the Fully decoupled code is as follows :-

    using System;
    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.Configuration;
    using System.Configuration;
    
    namespace DependencyInjection
    {
    class Program
        {
            static void Main(string[] args)
            {
                //Put these lines in startup event of any application
                IUnityContainer container = new UnityContainer();
                UnityConfigurationSection objSection = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
                objSection.Configure(container);
    
                Student objStudent = container.Resolve<Student>();
                objStudent.SaveStudent();
            }
        }
    
        //BAL Layer
        public class Student
        {
            private IDAL iSqlOracleDal;
    
            public Student(IDAL _iSqlOracleDal)
            {
                this.iSqlOracleDal = _iSqlOracleDal;
            }
    
            public void SaveStudent()
            {
                iSqlOracleDal.Save();
            }
        }
    
        //Interface
        public interface IDAL
        {
            void Save();
        }
    
        //DAL SQL Layer
        class SqlServerDAL : IDAL
        {
            public void Save()
            {
                Console.WriteLine("Save Data Using Sql Server.");
                Console.ReadLine();
            }
        }
    
        //DAL Oracle layer
        class OracleDAL : IDAL
        {
            public void Save()
            {
                Console.WriteLine("Save Data Using Oracle.");
                Console.ReadLine();
            }
        }
    }

    Now modify the WebConfig or AppConfig as follows :-

    <configuration>
      	<configSections>
        <section name="unity" 	type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
                 Microsoft.Practices.Unity.Configuration"/>
      </configSections>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
      </startup>
      <unity>
        <containers>
          <container>
            <types>
    
              <type type="DependencyInjection.IDAL,DependencyInjection"
                    mapTo="DependencyInjection.OracleDAL,DependencyInjection">
              
               <!--<type type="DependencyInjection.IDAL,DependencyInjection" 
                    mapTo="DependencyInjection.SqlServerDAL,DependencyInjection">--> 
              </type>
            </types>
          </container>
        </containers>
      </unity>
    </configuration>

    Code Execution Result as shown below :-

     

    If we use SqlServerDAL in our webconfig then it will use Sql Server DAL.

     

    Code Explanation :-

    I have used below lines to register our classes in the Unity container :-

    IUnityContainer container = new UnityContainer();
                UnityConfigurationSection objSection = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
                objSection.Configure(container);
    
    	Student objStudent = container.Resolve<Student>();

     

    Here UnityContainer is like a container where we register our classes.

    We will register the interface with service or repository classes in the web config as shown below :-

    <type type="DependencyCode.IDAL,DependencyCode"
                    mapTo="DependencyCode.OracleDAL,DependencyCode">

    Here DependencyCode is a NameSpace of class.

    This code is fully decoupled using Unity Application Block and it uses Constructor Injection. We have two more injection methodology :

    1. Setter Injection

    2. Interface-based injection

    I will explain these in my next blogs.

     

    6. Conclusion

    If we talk about the using dependency injection in each and every application, then you don't need to do it for every small application. Use dependency for large enterprise application where we have different layred architecture and repository pattern.

    Thanks.

    Happy Coding :-)

     

    Sorry for the variable names, as this is for learning purpose.

    References:- https://www.manning.com/books/dependency-injection-in-dot-net

       https://msdn.microsoft.com/en-in/library/ff649564.asp

     

 0 Comment(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: