Dependency Injection Techniques Explained

In my previous article on S.O.L.I.D principle part 5, I have demonstrated the principle of Dependency Injection using constructors. Now, this article just looks at the types of Dependency Injections and what Inversion of Control means. We also look at the use of one of the containers available for free download to learn how we can implement the DI using IOC.

I will use a simple case to understand the DI using IOC.

Recap on Dependency Injection

1.gif

Here the Class A object uses the services provided by Class B and the Class A object is depending on Class B. But the best practices of designing says that two class objects should not be tightly coupled and so, we need to break the coupling between the two classes.

An Interface is the mechanism for breaking this tight coupling between the two objects.

2.gif

Here the Class A object knows what type of class object it is going to use, but it has information on what is the service or operations it is going to consume by Interface type. At run time, the program that is going to create an instance of Class A is going to pass the actual class object as a parameter to its constructor or the set method of the public property of the class.

This avoids the direct dependencies between the concrete classes. Here is the sample code that we are going to use:

    class Program
    {
        static void Main(string[] args)
        {
            ClassA classA=new ClassA();
            classA.DoSomethingFromClassB();
        }
    }
    public interface IClassA
    {
        void DoSomethingFromClassB();
    }
    public class ClassA : IClassA
    {
        public void DoSomethingFromClassB()
        {
            ClassB classB = new ClassB();
            classB.DoSomething();
        }
    }   
    public interface IClassB
    {
        void DoSomething();
    }
    public class ClassB : IClassB
    {
        public void DoSomething()
        {
            Console.WriteLine("I am doing Somehing now");
        }
    }

IOC and DI

Usually we hear that Inversion of Control (IOC) and Dependency Injection (DI) are interchangeable. You might have been asked in interviews also like "Is IOC and DI the same? If not then how are they different?" The answer is as below:

IOC is the implementation of the DI principle. You can better understand that from the following definitions:

IOC means that objects do not create other objects on which they depend to do their work. Instead, the objects are supplied from an outside source. For example, an application configuration file or any tools. There are numerous tools available useable as a source for providing respective objects as needed. Some of the names of tools that are most used are: Autofac, Spring.NET, StructureMap, Ninject, Unity, ObjectBuilder etc.

You can download these tools as most of them are available as open source. Refer to the link for more details on these tools:

http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx

Dependency Injection (DI) means that this is done without object intervention, usually by a framework component that passes constructor parameters and set properties. This we have seen in the article on SOLID principle part 5.

So, IOC is just an implementation of the DI principle.

There are two major types of DI techniques available. One is Constructor Injection and other one Setter Injection.

Constructor Injection

In Constructor Injection technique, the dependent object is sent through the parameter of the constructor. The parameter accepted is not a concrete class type, but an interface type.

Here is the example that we have refactored to implement Constructor Injection:

  class Program
    {
        static void Main(string[] args)
        {
            IClassA classA=new ClassA(new ClassB());
            classA.DoSomethingFromClassB();
        }
    }
    public class ClassA : IClassA
    {
        private readonly IClassB _classB; 
        public ClassA(IClassB classB)
        {
            _classB = classB;
        } 
        public void DoSomethingFromClassB()
        {
            _classB.DoSomething();
        }
    }

Here we have injected a dependency object using a constructor of the class.

Setter Injection

In the Setter Injection technique, the dependent object is passed through a public property set accessor as the value. This avoids writing constructors in the class to accept the dependent object as a parameter.

To do this we need to change the interface IClassA to accommodate a property of type Class B.

    public interface IClassA
    {
        IClassB ClassB { get; set; }
        void DoSomethingFromClassB();
    }
    public class ClassA : IClassA
    {
        private IClassB _classB;
        public IClassB ClassB
        {
            get { return _classB; }
            set
            {
                if (value == null) throw new ArgumentNullException("value");
                _classB = value;
            }
        } 
        public void DoSomethingFromClassB()
        {
            _classB.DoSomething();
        }
    }
    static void Main(string[] args)
        {
            IClassA classA=new ClassA();//creating instance of class A
            classA.ClassB = new ClassB();//creating instance of class B and setting it to the property of class A
            classA.DoSomethingFromClassB();//calling the method
            Console.Read();
        }

So, in this technique we have introduced a dependency object using a public property of a class in the set method.

Comparison of two techniques

Out of the two techniques the most simple and useful technique is constructor since at the time of creation of the object itself, it is going to ask you to pass the parameter. Whereas in the second technique, you will not know the dependencies until you create an object.

There is one more type of injection we can work with; that is Method Injection. In Method Injection, the dependent object is injected using the Method of the class.

Method Injector


We use the same code, but we will modify it a little bit to accommodate the injection through Method as below:

    public interface IClassA
    {
        void DoSomethingFromClassB();
        void SetClassB(IClassB classB);
    } 
    public class ClassA : IClassA
    {
        private  IClassB _classB;       
        public void SetClassB(IClassB classB)
        {
            _classB = classB;
        } 
        public void DoSomethingFromClassB()
        {
            _classB.DoSomething();
        }
    } 
    class Program
    {
        static void Main(string[] args)
        { 
           IClassA classA = new ClassA();
           classA.SetClassB(new ClassB());
           classA.DoSomethingFromClassB();
           Console.Read();
        }
    }

In the preceding code, we are injecting the dependent object of type IClassB into ClassA using a Method which takes the parameter of type IClassB.

Now let us discuss an example on Inversion of Control. This dependency injector is not in the code, but outside of the code.

A simple method is by injecting the class from an application configuration file.

To do this use the following steps:

  • We need to create a key value pair in the section <appSettings> in the application configuration file.
  • Read the class to be loaded from the configuration file.
  • Using reflection to create an instance of the class.
  • Now use the instance of the class in your logic.

Note: Here we are not injecting the dependencies within the code, but through containers of the class information. In this example, we use a configuration file.

Here is our code for this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
      <appSettings>
            <add key="MyClassObject" value="BusinessClasses.ClassB, BusinessClasses, Version=1.0.0.0, Culture=neutral"/>
      </appSettings>
</configuration>

We are still using the code created for setter injection.

 
  class Program
    {
        static void Main(string[] args)
        {
            IClassA classA=new ClassA();//creating instance of class A
 
            //Read the class to be loaded from the application configuration file
            string loadedClass = ConfigurationManager.AppSettings["MyClassObject"].ToStrin
            (CultureInfo.InvariantCulture);
 
            //Get the type of the instance
            Type instanceType = Type.GetType(loadedClass);
            if (instanceType == null) throw new ArgumentNullException("args");
 
            //Now create the IClassB type instance using the reflection
            IClassB instance = (IClassB) Activator.CreateInstance(instanceType);
 
            //assign the instance to the classB property of class A
            classA.ClassB = instance; 

            //Call the method
            classA.DoSomethingFromClassB(); 
            Console.Read();
        }
    }

This is the simplest way to inject dependencies without any tools. Most financial companies would not trust the open sources and do not want to invest in tools without which if you are able to work on the code with no issues. So, this would be the simplest mechanism for developers working for such a company.

In this article we have discussed the basic techniques of dependency injections through code and also through a simple configuration file.

The benefits of DI can broadly be explained in the following terms:

  1. Reduced Dependencies.
  2. Reduced Dependency Carrying.
  3. More Reusable code.
  4. More Testable code.
  5. More Readable code.

In our next articles, we see how to use Containers to handle the dependency injection.

X

Build smarter apps with Machine Learning, Bots, Cognitive Services - Start free.

Start Learning Now