Powered by Blogger.

Knowledge Dojo

    • Home
    • JavaScript
    • _Concepts
    • Unity
    • C#
    • About
    • Contact
    Dependency injection is a design pattern that allows us to create loosely coupled classes.
    To understand loosely coupled classes, let us understand there opposite i.e. tightly coupled classes.

    Tightly Coupled Classes Example

    tight coupling between classes

    Consider this two classes:
    public class Class1: IClass1
    {
     public IClass2 class2;
    
     public Class1()
     {
      class2 = new Class2();
     }
    }
    
    public class Class2: IClass2
    {
    }

    instance of class 2 injected in class 1


    As you can see, Class 1 instantiates the object of Class 2 in its constructor.

    What if the logic for object instantiation for class 2 changes, class 1 also needs to be changed. This is called tight coupling between classes. To prevent such scenario, we use a design pattern called dependency injection.

    What is dependency injection?

    According to dependency injection, instead of instantiating the dependency object in a class, we just pass the dependency along with the object in its constructor.

    Dependency Injection may also be called as Inversion Of Control (IoC) as it follows the Hollywood Principle
    "Don't call us, We will call you."

    Dependency Injection In Action

    This can be well explained with the help of this example:

    Consider the architecture of a MathsCalculator class such that it is the concrete implementation of interface IMathsCalculator. The MathsCalculator class uses a MathsService instance to compute mathematical calculations like SquareRoot, CubeRoot etc.

    Here we will be using the dependency injection design pattern to decouple the two classes MathsCalculator and MathsService.

    class MathsCalculator: IMathsCalculator
    {
     IMathsService mathsService;
    
     MathsCalculator(IMathsService mathsServiceInstance)
     {
      mathsService = mathsServiceInstance;
     }
    
     float SquareRoot(float num)
     {
      float num = this.mathsService.sqrt(num);
      return num;
     }
    }
    
    void main()
    {
     IMathsService mathsService = new MathsService();
     IMathsCalculator mathsCalculator = new MathsCalculator(mathsService);
    
     float result = mathsCalculator.SquareRoot(5);
    
     Console.WriteLine(" Square Root: "+result);
    }
    
    Observe the way we injected the mathsService instance in the MathsCalculator object's constructor.

    This method to inject a dependent object in other class object is called as dependency injection.

    The main objective of the concept is that the class using service instances need not know about the service instantiation. It all should know about using the instance.
    Inversion of control is called so because it inverts the procedural programming flow.
    Instead of the class looking for its dependency to instantiate, we provide the class object with the instantiated dependency.

    Advantage of using Dependency Injection

    The advantage of using Dependency Injection is it simplifies unit testing of the project. Consider if the service injected makes use of internet services, messaging services, etc such that they only need to be mocked in unit testing. While executing the unit testing, we can provide a mock internet service or a mock messaging service, so that we do not end up with actual messaging to real people while unit testing the code.

    Now consider the scenario when there are nested dependencies injected like
    Class1 has dependency Dependency1
    Dependency1 has dependency Dependency2

    The code for instantiating the instance of Class 1 would be like:
    var instance = new Class1(new Dependency1(new Dependency2()));
    This looks a bit confusing. To prevent this, we use DI Containers. I have created a separate article on DI Containers which can be found here.
    Implementing the DI Containers >

    DI (Dependency Injection) Container/IoC (Inversion of Control) Container

    DI Container or IoC container are the terms that are used interchangeably but have the same meaning.

    What is it?

    Consider using the following code to instantiate a class with multiple services:
    var instance = new Class1(new Service1(), new Service2(new Service3()), new Service4());


    nesting of dependencies in dependency injection


    Will you prefer using the code as the one above?
    The answer would be NO as this is really fussy and confusing code to find out what is actually going on here.

    To solve the above problem, we use the DI Container, that helps us simplify the above code to human readable and understandable extent.

    Definition

    A DI Container is a framework that automatically creates the objects and injects the dependencies when required.
    To simplify the fuss related to creating instances( sometimes nested ) and injecting them, we use the DI container.

    With a DI Container used, the code will look something like:
    var instance = container.Resolve<Class1>();

    But how to implement this?

    This can be well explained with this detailed example below.
    There are a lot of DI Container frameworks in the market like Unity, Castle Windsor, StructureMap, Ninject etc. I will be using the Unity DI Container for this example.

    Installing Unity DI Container

    We will install Unity DI Framework with the Unity's NuGet package. To install the NuGet package, follow these steps:
    Step 1: Right-click the project name in the solution explorer and Click on "Manage NuGet Packages"

    Step 2: With the browse option selected, search for "Unity" and click on the download icon against it. Click Ok if you are prompted for installation.


    Implementing the Unity DI Container
    Consider a class Class1 such that it needs a dependency Dependency1. The class Dependency1 needs another dependency class Dependency2.
    class Class1 
    {
        IDependency1 dependency1;
        public Class1(IDependency1 dependency)
        {
            dependency1 = dependency;
        }
    }
    
    class Dependency1 
    {
        IDependency2 dependency12
    
        public Dependency1(IDependency2 dependency)
        {
            dependency2 = dependency;
        }
    }
    
    So the class object instantiation would look like:
    Class1 instance = new Class1(new Dependency1(new Dependency2()));
    Thus creating a nested dependency in the instantiation of the Class1 object.
    But this object instantiation looks a bit confusing and we need to sort this out.

    Implementing the DI Container

    Let's start using Unity DI Container.
    In our C# console application, first we need to import the Unity Namespace by adding a following reference to the import statements:
    using Unity;

    Now we need to register the types that will be injected whenever we need a service/dependency like whenever we need a IDependency1 service, the DI container will automatically inject the Dependency1 class instance.

    The syntax for registering the mapping between the type of object to be received and the actually needed object is:
    var container = new UnityContainer();
    
    container.RegisterType<IClass1, Class1>();
    container.RegisterType<IDependency1, Dependency1>();
    container.RegisterType<IDependency2, Dependency2>();

    All statements look similar. So what do these statements mean?
    Let's look at it.

    The format is something like:
    container.RegisterType<RequiredType, SuppliedType>();
    i.e. whenever an object of a IClass1 is required, the instance of Class1 object will be automatically passed by the DI Container.

    Now instead of instantiating Class1 object as:
    var instance = new Class1( new Dependency1( new Dependency2() ) );

    With the use of DI Container, I will simply instantiate Class1 object as:
    var instance = container.Resolve<IClass1>();

    The Container instance provides a resolve method that will automatically resolve the dependency and will supply the instance of Class1. Since Class1 further have IDependency1 needed, the DI Container will automatically pass a new instance of Dependency1 and so on.

    The final Code for the C# Console application will look like this:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Unity;
    
    namespace ConsoleApp1
    {
        class Class1 : IClass1
        {
            IDependency1 dependency1;
    
            public Class1(IDependency1 dependency)
            {
                dependency1 = dependency;
            }
        }
    
        class Dependency1 : IDependency1
        {
            IDependency2 dependency2;
    
            public Dependency1(IDependency2 dependency)
            {
                dependency2 = dependency;
            }
        }
    
        class Dependency2 : IDependency2
        {
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var container = new UnityContainer();
    
                container.RegisterType<IClass1, Class1>();
                container.RegisterType<IDependency1, Dependency1>();
                container.RegisterType<IDependency2, Dependency2>();
    
                var instance = container.Resolve<IClass1>();
    
                Console.ReadKey();
            }
        }
    }
    Older
    ARTICLES

    IEnumerable vs ICollection vs IList vs IQueryable in C#

    Popular Posts

    • Audio latency on Unity 3d Android Platform
    • HTTP Interceptor in Angular 4

    Created with by BeautyTemplates

    Back to top