Dependency Injection Using Unity – Resolve Dependency Of Dependencies

This article will not be very theoretical, but would be more of a tutorial to showcase the existing problems with tightly coupled applications, how to make the application loosely coupled and achieve inversion of control via dependency injection.

Advertisements

Introduction

Inversion of control (IOC) and Dependency Injection (DI) work hand in hand and makes our application more loosely coupled and easy to expand. It is strongly recommended to follow SOLID principles when it comes to development. This article will not be very theoretical but would be more of a tutorial to showcase the existing problems with tightly coupled applications, how to make the application loosely coupled and achieve inversion of control via dependency injection, solve the problem of resolving dependency of a dependency in a three-layered/n layered project architecture using unity framework. You can get the downloadable source code at the end of the article.

Problem

While working on a three-layered architecture, there could be situations where applications at higher level modules/layers/classes are dependent on lower level modules. If we consider a basic simplistic example, an application can have a presentation layer, a business layer and a data access layer in a three-layered architecture. Presentation layer talks to the business layer, business layer in turn talks to data access layer. To call a method of business layer in the presentation layer, it is needed to create an object of business layer class in the presentation layer and then call that method needed. To call the method of a class in data access layer, business layer class needs to create an object of the class in data access layer and then invoke that method. Business layer communicates with data access layer because due to architectural constraints and flexibility, we do not want our presentation layer talking to data access layer as shown below.

Dependency Injection Using Unity

Considering, that the readers of this tutorial already know how to resolve dependency of modules, it is needed that presentation layer itself does not create an object of business layer but delegates this responsibility to any third-party container and when the instance is needed then that object is created for the presentation layer, i.e., dependency injected and methods of business layers could be accessed via that. Same goes for communication between the business layer to data access layer. This is where Unity comes into the picture. Unity acts as a container for this object creation and dependency resolution. Our problem is a bit different. Using unity at the presentation layer, we can resolve the dependency of business layer, but what about data access layer? How do we resolve dependency on data access layer in business layer? Do we need to again write a container in business layer? One way to achieve this is already explained in one of my previous articles, where we can make use of MEF (Managed Extensibility Framework), but in this tutorial, we’ll even use a very simple way to do this. Let’s write some code, first to see the problem and then towards a step-by-step solution.

Create Application Without DI

Since the focus area of this article, is to explain the use of unity to resolve dependency of dependency in a simplistic way, we’ll not create a large application, but a small three-layered console application with only one class in each layer and one method in each class for the proof of concept. One can create MVC or any other application or can use this solution as a POC in any big application.

Step 1

Open Visual Studio. Create a console application and name it Presentation, add a class library and name it Business, add another class library and name that Data. So, we segregate our layers with these class libraries, where a Business class library is for a Business layer and Data class library is for Data access layer. The solution should look like something as follows. I have named the solution as “WithoutDI”.

Dependency Injection Using Unity

Remove the default classes named Class1.cs from Business and Data class libraries.

Dependency Injection Using Unity

Step2

Now, add a class named BusinessClass in the Business project and DataClass in Data project. Add a method named GetData in the DataClass and return any string from that method. So, the implementation of the class looks like follows.

  1. namespace Data
  2. {
  3.   public class DataClass
  4.   {
  5.     public string GetData()
  6.     {
  7.       return “From Data”;
  8.     }
  9.   }
  10. }

Step 3

Now, our requirement is to get this data coming from GetData method into our presentation layer and show on the console. The straightforward way is that we call a method of Business class from presentation’s layer Program.cs that in turn will call this GetData method from DataClass. To achieve this, we first need to add the reference to the Business project in the Presentation console application and reference of Data project in Business class library.

Dependency Injection Using Unity

Step 4

Now, to access GetData method of Data project’s DataClass from BusinessClass, we first need the instance of DataClass in BusinessClass. We create the instance in BusinessClass constructor and then there should be a method in Business class that then makes use of this DataClass instance to call GetData method to return the string. So, the implementation looks like as follows.

  1. using Data;
  2. namespace Business
  3. {
  4.   public class BusinessClass
  5.   {
  6.     DataClass _dataClass;
  7.     public BusinessClass()
  8.     {
  9.        _dataClass = new DataClass();
  10.     }
  11.     public string GetBusinessData()
  12.     {
  13.       return _dataClass.GetData();
  14.     }
  15.   }
  16. }

Step 5

Now, to class this GetBusinessData method of Business class from the presentation layer, we again need to create an instance of BusinessClass class in the presentation layer and call the method. To create an instance of BusinessClass in the main method or Program.cs and call the GetBusinessData via that instance as follows.

  1. using System;
  2. namespace Presentation
  3. {
  4.   class Program
  5.   {
  6.     static void Main(string[] args)
  7.     {
  8.       Business.BusinessClass businessClass = new Business.BusinessClass();
  9.       string data = businessClass.GetBusinessData();
  10.       Console.WriteLine(data);
  11.       Console.ReadLine();
  12.     }
  13.   }
  14. }

When we run the application, we get our desired output as shown below.

Dependency Injection Using Unity

That means that our data comes from DataClass’s GetData() method. Our application runs fine, but the question is that, is it following SOLID principles? Is my application loosely coupled and autonomous, Is my application robust? If we look closely and try to answer these questions, the answer is, NO.

Application violates Single Responsibility Principle where classes are also doing an additional job of creating objects of dependent classes.

Application violates the Open-Close principle as, in case the constructor implementation changes in the classes, the calling class will have to modify its code to that change which may break the application or may not be feasible always.

Application violates Interface Segregation Principle indirectly as well as the testability of the application is very poor as we do not have interfaces defined for the classes that serve as a contract.

Application violated Dependency Inversion principle as classes are dependent on other classes instances and are directly creating instances in the class. Imagine a situation where instance creation of DataClass fails, due to which Business class constructor will also fail to initialize and throw an error. Which is not at all acceptable.

So, four out of five principles are violated. Moreover, the application is not testable w.r.t. unit tests. The application is tightly coupled. Let’s try to resolve these issues one by one with the help of Unity Framework and also proceed to see how we can resolve dependency of dependency.

Introduce Unity in the Application

Time to introduce Unity in the application. Unity Framework comes as a NuGet package, so we’ll install it via Package Manager Console. Open Tools in Visual Studio, navigate to Nuget Package Manager and open Package Manager Console as shown in below image.

Dependency Injection Using Unity

When the package manager console is opened. Type command Install-Package Unity to get the latest version of Unity framework. Make sure Presentation project is selected as the default project in the console. After typing the command when we press enter, Unity package is installed for the presentation project. The latest version that I got is 5.7.3. it may vary and depends when you are implementing this based on latest versions released.

Dependency Injection Using Unity

There would be one packages.config file created in the application where this Unity package would be referenced and the package itself would be downloaded in the file system in packages folder and the same would be referenced automatically in the Presentation project.

Dependency Injection Using Unity

Dependency Injection via Unity

Let’s do some modification in the Presentation layer and instead of calling BusinessClass method from the Main method, let’s add a class named Initiator and call the method from there. We could have done this earlier, but we missed, so let’s do it now. This is just to understand more clearly, how we resolve dependencies. So, add a class named Initiator and add following code.

  1. using Business;
  2. namespace Presentation
  3. {
  4.   public class Initiator
  5.   {
  6.     BusinessClass _businessClass;
  7.     public Initiator()
  8.     {
  9.       _businessClass = new BusinessClass();
  10.     }
  11.     public string FetchData()
  12.     {
  13.       return _businessClass.GetBusinessData();
  14.     }
  15.   }
  16. }

Dependency Injection Using Unity

Code for Program.cs becomes as follows,

  1. using System;
  2. namespace Presentation
  3. {
  4.   class Program
  5.   {
  6.     static void Main(string[] args)
  7.     {
  8.       Initiator initiator = new Initiator();
  9.       string data = initiator.FetchData();
  10.       Console.WriteLine(data);
  11.       Console.ReadLine();
  12.     }
  13.   }
  14. }

The output and logic remains same, we just moved few pieces from Program.cs to Initiator class and in Main method now use this Initiator class instance to fetch data.

So, the problem here now is, Program.cs Main() method creates an instance of Initiator class, Initiator class creates an instance of BusinessClass, and Business class creates an instance of DataClass to fetch data. Let’s give this responsibility of instance creation to someone else i.e. Unity and we inject the dependency in the defined constructors via Interfaces. Yes, we now need to create interfaces and define the respective methods. Let’s do it step-by-step.

Step1

Create an interface named IData in Data project and define the GetData () method there as shown below.

  1. namespace Data
  2. {
  3.   public interface IData
  4.   {
  5.     string GetData();
  6.   }
  7. }

Now, implement this interface in DataClass as shown below,

  1. namespace Data
  2. {
  3.   public class DataClass : IData
  4.   {
  5.     public string GetData()
  6.     {
  7.       return “From Data”;
  8.     }
  9.   }
  10. }

Step2

Now, come to the Business project and define an interface named IBusiness and define the GetBusinessData() method there as shown below.

  1. namespace Business
  2. {
  3.   public interface IBusiness
  4.   {
  5.     string GetBusinessData();
  6.   }
  7. }

Implement this interface in BusinessClass as follows,

  1. using Data;
  2. namespace Business
  3. {
  4.   public class BusinessClass
  5.   {
  6.     DataClass _dataClass;
  7.     public BusinessClass()
  8.     {
  9.        _dataClass = new DataClass();
  10.     }
  11.     public string GetBusinessData()
  12.     {
  13.       return _dataClass.GetData();
  14.     }
  15.   }
  16. }

Now, let’s assume that Business class will no more take this responsibility of object creation and this dependency would be injected in BusinessClass constructor on runtime and we’ll have an object at runtime to call GetData method of DataClass. So, our Business class looks something like following,

  1. using Data;
  2. namespace Business
  3. {
  4.   public class BusinessClass : IBusiness
  5.   {
  6.     IData _dataClass;
  7.     public BusinessClass(IData dataClass)
  8.     {
  9.       _dataClass = dataClass;
  10.     }
  11.    public string GetBusinessData()
  12.     {
  13.       return _dataClass.GetData();
  14.     }
  15.   }
  16. }

It is pretty straightforward. We declare IData instance local variable and expecting IData instance in the constructor of BusinessClass at runtime, which we assign to our local variable and in the method GetBusinessData(), we make use of this local variable assuming it would be initialized well in advance, we call the GetData() method. Note that no “new” keyword here is used to create an instance and now BusinessClass also does not takes this responsibility of creating objects of DataClass. This code will still not work. We need to do some homework in our presentation layer as well.

Step3

Move to Presentation project and do the same thing as we did in the Business layer for DataClass, but now in Initiator class for a Business layer. So, our Initiator class looks like as shown below,

  1. using Business;
  2. namespace Presentation
  3. {
  4.   public class Initiator
  5.   {
  6.     IBusiness _businessClass;
  7.     public Initiator(IBusiness businessClass)
  8.     {
  9.       _businessClass = businessClass;
  10.     }
  11.     public string FetchData()
  12.     {
  13.       return _businessClass.GetBusinessData();
  14.     }
  15.   }
  16. }

This is also easy to understand. We declare IBusiness instance local variable, then in the constructor, we assume that we get the pre-initialized instance of a business class and assign the same to our local variable and call GetBusinessData() method via that. Note, that we completely removed the “new” keyword from here and this class also does not take this responsibility to create objects. Our job is still not done. We still have Main() method in the program.cs class that creates an object of Initiator class via “new” keyword and class the FetchData() method. Our goal is to completely get rid of this “new” keyword and make sure classes follow Single Responsibility Principle.

Step4

Add a new class named DependencyInjector in the Presentation project and add following code to it.

  1. using Unity;
  2. using Unity.Lifetime;
  3. namespace Presentation
  4. {
  5.   public static class DependencyInjector
  6.   {
  7.     private static readonly UnityContainer UnityContainer = new UnityContainer();
  8.     public static void Register<I, T>() where T : I
  9.     {
  10.       UnityContainer.RegisterType<I, T>(new ContainerControlledLifetimeManager());
  11.     }
  12.     public static void InjectStub<I>(I instance)
  13.     {
  14.       UnityContainer.RegisterInstance(instance, new ContainerControlledLifetimeManager());
  15.     }
  16.     public static T Retrieve<T>()
  17.     {
  18.       return UnityContainer.Resolve<T>();
  19.     }
  20.   }
  21. }

This DependencyInjector class is a generic class that takes care of resolving types and registering types. It makes use of Unity to register an instance of any type coming to it. We could have made it specific to our classes and interfaces, but it is always better to be generic to entertain whatever new types come to our application in future.

To define and register our concrete types, i.e., IBusiness and Business class, add another class named Bootstrapper to the presentation project. This class acts as its name, i.e., Bootstrapper for our application, i.e., first class to resolve dependencies beforehand as soon as our application loads. So, add Bootstrapper.cs and add following code to it.

  1. using Business;
  2. namespace Presentation
  3. {
  4.   public static class Bootstrapper
  5.   {
  6.     public static void Init()
  7.     {
  8.       DependencyInjector.Register<IBusiness, BusinessClass>();
  9.     }
  10.   }
  11. }

This class just calls generic Register method of DependencyInjector class and requests to resolve dependency of BusinessClass, so that when needed, the instance of Business class would be supplied.

Step 5 

In the Main method, now just call this Init() method of Bootstrapper class to register the types and get an instance of Initiator class via Retrieve method of DependencyInjector class. We need this Initiator instance to call FetchData method of Initiator class. So following is the code of our Program.cs class.

  1. using System;
  2. namespace Presentation
  3. {
  4.   public class Program
  5.   {
  6.     static void Main(string[] args)
  7.     {
  8.       Bootstrapper.Init();
  9.       Initiator initiator = DependencyInjector.Retrieve<Initiator>();
  10.       string data = initiator.FetchData();
  11.       Console.WriteLine(data);
  12.       Console.ReadLine();
  13.     }
  14.   }
  15. }

Simple, Crisp and clear. Note that we got rid of the “new” keyword from here also and the main responsibility of this class is initialization and application start-up.

In a nutshell, we did the following,

  1. Introduced the generic DependencyInjector class to take care of registering/resolving types.
  2. Introduced Bootstrapper class that calls DependencyInjector class methods in its Init() method for registering concrete types.
  3. In the Main method of Program.cs invoked Init method of Bootstrapper class, so that types are registered and resolved at the start of the application.
  4. Called our FetchData() method from Initiator class.

To, me everything looks fine and we are all set to run the application.

Step6

Run the application by hitting F5. We assumed everything would work fine as we took care of dependencies, but wait a minute what we got. We got following run time error.

Dependency Injection Using Unity

When you check the InnerException, the error is obvious and self-explanatory. It says, “-            InnerException          {“The current type, Data.IData is an interface and cannot be constructed. Are you missing a type mapping?”}        System.Exception {System.InvalidOperationException}”

Yes, you are right. We took care of registering BusinessClass with IBusiness. We took care of resolving Initiator class instance but what about DataClass? Remember, we removed “new” from BusinessClass constructor as well when we try to get DataClass instance, but we have not yet registered the type nor resolved it to be used when needed.

The solution is that we need to register type for DataClass as well so that we get its instance when needed. But how to do it? We cannot access or reference the Data project in presentation layer as it will violate our layered architecture. So, the only place is a Business project. But again, if we do it altogether that we did in the Presentation layer, it will not make sense and would have code duplication and two bootstrappers in the application. One way is MEF that I already explained in one of my previous articles but that method is a bit complex. Let’s explore how we can overcome this situation without referencing Data project in presentation project, without code duplication, without multiple and confusing/hard to manage bootstrappers and without SOLID/coupling violation.

Resolve Dependency on Dependency using Unity Extensions

Unity provides this flexibility to resolve dependency of dependencies without structure violation via UnityContainerExtensions as shown below,

  1. namespace Unity.Extension
  2. {
  3.   public abstract class UnityContainerExtension: IUnityContainerExtensionConfigurator
  4.   {
  5.     protected UnityContainerExtension();
  6.     public IUnityContainer Container { get; }
  7.     protected ExtensionContext Context { get; }
  8.     public void InitializeExtension(ExtensionContext context);
  9.     public virtual void Remove();
  10.     protected abstract void Initialize();
  11.   }
  12. }

This class is part of Unity.Abstractions dll and contains an abstract method named Initialize(). Abstract method means we can override this method and write our custom initialization logic. So, let’s do that.

Create a class named DependencyOfDependencyExtension in the Business project. You can name the class as per your choice. I named the class in this way for the sake of understanding. Install Unity package in the Business project in the same way as we did for presentation project. Do not forget to choose Business as the default project in package manager console as shown below.

Dependency Injection Using Unity

Step1

Once Unity is added to the project as was in the presentation layer, add following namespaces to our newly created DependencyOfDependencyExtension class,

  1. using Data;
  2. using Unity;
  3. using Unity.Extension;

Now, inherit the class from UnityContainerExtension class present in Unity.Extension namespace of Unity.Abstractions assembly and override its Initialize method as follows to register DataClass type with IData.

  1. using Data;
  2. using Unity;
  3. using Unity.Extension;
  4. namespace Business
  5. {
  6.   public class DependencyOfDependencyExtension : UnityContainerExtension
  7.   {
  8.     protected override void Initialize()
  9.     {
  10.       Container.RegisterType<IData,DataClass>();
  11.     }
  12.   }
  13. }

Step2

Now, we must make our presentation layer know about this extension. So, move to the presentation layer and in the DependencyInjector class add a new generic method named AddExtension() to add new extensions as shown below,

  1. public static void AddExtension<T>() where T : UnityContainerExtension
  2.     {
  3.       UnityContainer.AddNewExtension<T>();
  4.     }

Do not forget to add using Unity.Extension;namespace to this class to access UnityContainerExtension class. Complete class is as follows.

  1. using Unity;
  2. using Unity.Extension;
  3. using Unity.Lifetime;
  4. namespace Presentation
  5. {
  6.   public static class DependencyInjector
  7.   {
  8.     private static readonly UnityContainer UnityContainer = new UnityContainer();
  9.     public static void Register<I, T>() where T : I
  10.     {
  11.       UnityContainer.RegisterType<I, T>(new ContainerControlledLifetimeManager());
  12.     }
  13.     public static void InjectStub<I>(I instance)
  14.     {
  15.       UnityContainer.RegisterInstance(instance, new ContainerControlledLifetimeManager());
  16.     }
  17.     public static T Retrieve<T>()
  18.     {
  19.       return UnityContainer.Resolve<T>();
  20.     }
  21.     public static void AddExtension<T>() where T : UnityContainerExtension
  22.     {
  23.       UnityContainer.AddNewExtension<T>();
  24.     }
  25.   }
  26. }

Step3

We are almost done, now Add concrete type for this extension in Bootstrapper’s class Init method as follows,

  1. using Business;
  2. namespace Presentation
  3. {
  4.   public static class Bootstrapper
  5.   {
  6.     public static void Init()
  7.     {
  8.       DependencyInjector.Register<IBusiness, BusinessClass>();
  9.       DependencyInjector.AddExtension<DependencyOfDependencyExtension>();
  10.     }
  11.   }
  12. }

Job done, just run the application and we see our desired output as shown below,

Dependency Injection Using Unity

Dependency Injection Using Unity

In this way, we resolved dependency of dependency that is dependency(DataClass) of dependency (BusinessClass) to the presentation layer.

Summary

Let’s do the quick summary of what we did in our application and complete tutorial.

  1. We created a three-layered basic architecture with presentation, business, and data access layer. The architecture was tightly coupled and violated SOLID.
  2. We introduced Unity to resolve dependency between presentation and business layer. Thereafter we used constructor injection to inject dependencies via interfaces.
  3. We resolved dependency of dependency using Unity Extensions so that our architecture is not breached.
  4. We got rid of “new” keywords and delegated the responsibility of object creation to Unity container.
  5. We achieved inversion of control via dependency injection.
  6. Every class has a single responsibility and is open to extension and not modification.
  7. We achieved Abstraction with the help of interfaces.Dependency Injection Using Unity

Conclusion

In this tutorial, we tried to learn dependency injection with the help of a simple example. The example taken is very basic, but the concept could be applied in MVC, Web API or any enterprise level application to resolve dependencies and achieve inversion of control with dependency injection. We also resolved dependency of dependencies with unity extensions. There could be more methods to resolve dependencies like property injection or service locator. We used constructor injection in our application. One can make use of other containers instead of Unity. I used Unity as I am more comfortable with it. Hope you enjoyed the article. Happy coding 🙂

Downloads :  SourceCodeWithoutDI   SourceCodeWithDI   PDF_Article

Author: Akhil Mittal

Akhil Mittal is a Microsoft MVP,C# Corner MVP, Code project MVP, blogger, programmer by heart and currently working as a Sr. Analyst in Magic Software and have an experience of more than 9 years in C#.Net. He holds a B.Tech in Computer Science and hold a diploma in Information Security and Application Development. His work experience includes Development of Enterprise Applications using C#,.Net and Sql Server,Analysis, Product Management as well as Research and Development. He is a MCP in Web Applications(MCTS-70-528,MCTS-70-515) and .Net Framework 2.0 (MCTS-70-536).