Dependency Injection Normal Way vs MEF vs Unity

Introduction

 
Dependency Injection is a design pattern used to fulfill the requirement of a class to achieve its goal or responsibility. (i.e. if a ClassX is using multiple other class objects inside, such as ClassA, ClassB, ClassC.) So, if we want to use ClassX, we need to have an instance of ClassA, ClassB, ClassC inside ClassX before initiating ClassX. ClassX has a dependency of ClassA, ClassB, ClassC. To resolve this dependency, there are multiple methods. In general, resolving (injecting) the dependency of a class is called Dependency injection.
 
We will try resolving dependency injection with 3 ways:
  • Using Injection Constructor level
  • Using MEF injection
  • Using Unity injection
We will see these methods using examples.
 
Let’s have a ShowRoom class. This ShowRoom class has a dependency on Bike, a Car class dependency at the method GetBikeDemo and it uses GetCarDemo to perform its action. Below is the code of the Car and Bike classes:
  1. using static System.Console;  
  2.   
  3. namespace Sample.DependencyInjection.Business  
  4. {  
  5.     public class Car  
  6.     {  
  7.         public void DriveDemo()  
  8.         {  
  9.             WriteLine("Car drive demo done");  
  10.         }  
  11.     }  
  12. }  
  1. using static System.Console;  
  2.   
  3. namespace Sample.DependencyInjection.Business  
  4. {  
  5.     public class Bike  
  6.     {  
  7.         public void DriveDemo()  
  8.         {  
  9.             WriteLine("Bike drive demo done");  
  10.         }  
  11.     }  
  12. }  

Injection at the Constructor level

 
In this case, we will inject the dependency class objects at constructor so that whoever accessing the main class, while initializing they will come to know, they need to create an instance of some other class(es) to use the main class.
 
In the below example, the ShowRoom class has a dependency of Bike, a Car class dependency at the method GetBikeDemo, and a GetCarDemo respectively. We can see that at the ShowRoom constructor we are passing Bike and Car objects to perform GetBikeDemo and GetCarDemo method action. As we are passing dependency objects in the constructer level, it is called a constructor level injection.
 
Below is the code of the ShowRoom class:
  1. namespace Sample.DependencyInjection.Business  
  2. {  
  3.     public class ShowRoom  
  4.     {  
  5.         private Car car;  
  6.         private Bike bike;  
  7.   
  8.         /// <summary>  
  9.         /// This is the constructor level injection  
  10.         /// </summary>  
  11.         /// <param name="car"></param>  
  12.         /// <param name="bike"></param>  
  13.         public ShowRoom(Car car, Bike bike)  
  14.         {  
  15.             this.car = car;  
  16.             this.bike = bike;  
  17.         }  
  18.   
  19.         public void GetCarDemo()=> car.DriveDemo();  
  20.   
  21.         public void GetBikeDemo()=> bike.DriveDemo();  
  22.     }  
  23. }  
Unfortunately, in the future, if we have the requirement of adding a method GetBicycleDemo, we need to create class Bicycle off course. We need to pass the Bicycle class object in the constructor. Wherever we are creating an instance of ShowRoom class, we need to add the Bicycle object as a dependency.
 
We will use regression testing at all places we create an instance of ShowRoom class. This is not the best practice to do. In the same way, if we pass objects at the method level (i.e. as parameters of methods we call it Method level injection.)
 
Dependency injection can be also achieved by having getter setter property, and if initiate the class at setter level, it is called a Setter level injection. (i.e. after creating an instance of the main class and before accessing the dependent method we need to set the property.) Again, in both cases, we will have the drawback which we already discussed above.
 
To avoid this above problem, we have 2 solutions, 1 using the MEF framework and another using Unity Framework.
 
Now we will see dependency injection using the MEF framework.
 
MEF is a managed extensibility framework. It's a light-weight framework to build a plugin solution. At the base level, MEF will use reflection.
 
In MEF the class or interface, we want to add it as a dependency. Therefore, we need to mention the class/interface with an Export decorator. In our example, Car and Bike were dependency classes. I will mention the Export decorator to the classes as shown below for both Car and Bike.
  1. using System.ComponentModel.Composition;  
  2. using static System.Console;  
  3.   
  4. namespace MEF.DependencyInjection.Business  
  5. {  
  6.     [Export]  
  7.     public class Bike  
  8.     {  
  9.         public void DriveDemo()  
  10.         {  
  11.             WriteLine("Bike drive demo done");  
  12.         }  
  13.     }  
  14. }  
  1. using System.ComponentModel.Composition;  
  2. using static System.Console;  
  3.   
  4. namespace MEF.DependencyInjection.Business  
  5. {  
  6.     [Export]  
  7.     public class Car  
  8.     {  
  9.         public void DriveDemo()  
  10.         {  
  11.             WriteLine("Car drive demo done");  
  12.         }  
  13.     }  
  14. }  
Below is the showroom class:
  1. using System.ComponentModel.Composition;  
  2. using System.ComponentModel.Composition.Hosting;  
  3. using System.IO;  
  4. using System.Reflection;  
  5.   
  6. namespace MEF.DependencyInjection.Business  
  7. {  
  8.     public class ShowRoom  
  9.     {  
  10.         [Import]  
  11.         private Car car;  
  12.         [Import]  
  13.         private Bike bike;  
  14.   
  15.         private CompositionContainer _container;  
  16.   
  17.         /// <summary>  
  18.         /// This is the Dependency injection using MEF  
  19.         /// </summary>  
  20.         /// <param name="car"></param>  
  21.         /// <param name="bike"></param>  
  22.         public ShowRoom()  
  23.         {  
  24.             var catalog = new AggregateCatalog();  
  25.             catalog.Catalogs.Add(new AssemblyCatalog(typeof(ShowRoom).Assembly));  
  26.             catalog.Catalogs.Add(new DirectoryCatalog(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)));  
  27.             _container = new CompositionContainer(catalog);  
  28.             _container.ComposeParts(this);  
  29.         }  
  30.   
  31.         public void GetCarDemo() => car.DriveDemo();  
  32.   
  33.         public void GetBikeDemo() => bike.DriveDemo();  
  34.     }  
  35. }  
In the above code, we can see that in the constructor we are not passing any params. To fulfill the dependency injection needed, we are using two assemblies 
  • System.ComponentModel.Composition
  • System.ComponentModel.Composition.Hosting
We have created 2 fields with the names car and bike. For both, we are mentioning the decorator Import. From this, CompositionContainer will get all exported types from assemblies that need to be imported in the current class.
 
Now we will see dependency injection using Unity framework. To get this framework, install it from the Nuget manager.
 
Dependency Injection Using Normal Way Vs MEF Vs Unity
 
From a usage point of view, Unity is quite easier to use. If we have any dependency, we just need to call it with the method Resolve<T>, as shown below:
  1. namespace Unity.DependencyInjection.Business  
  2. {  
  3.     public class ShowRoom  
  4.     {  
  5.         private Car car;  
  6.         private Bike bike;  
  7.   
  8.         /// <summary>  
  9.         /// This is the dependency injection using Unity  
  10.         /// </summary>  
  11.         /// <param name="car"></param>  
  12.         /// <param name="bike"></param>  
  13.         public ShowRoom()  
  14.         {  
  15.             var container = new UnityContainer();  
  16.             car = container.Resolve<Car>();  
  17.             bike = container.Resolve<Bike>();  
  18.         }  
  19.   
  20.         public void GetCarDemo() => car.DriveDemo();  
  21.   
  22.         public void GetBikeDemo() => bike.DriveDemo();  
  23.     }  
  24. }  
In the above code, we can see that to fulfill the need of dependency classes, in the constructor we are just instantiating UnityContainer and calling the Resolve<T> method to create an instance to the required class.
 
Below is the common output snap of all 3 dependency injection codes:
 
Dependency Injection Using Normal Way Vs MEF Vs Unity 
 
For your reference, source code has been uploaded with the article. You can download and use it.
 

Summary

 
In this article, we learned about the usage of dependency injection using MEF and Unity framework and also without using any framework by injecting at the constructor level.