Wednesday, April 22, 2020

Dependency Injection in C#

When designing an object oriented application, a major concern of design is "Design must be loosely coupled", which means that objects should have only those dependencies which are required doing their task and it must be fewer. Object dependencies should be an interface not on "concrete" objects. Loose coupling offers us greater reusability, maintainability, and testability.

There are three basic types of Dependency Injection
  1. Construction Injection
  2. Setter Injection
  3. Interface based Injection.

Constructor Injection


The basic idea of constructor-injection is that the object has no defaults or single constructor; instead specified values are required at the time of creation to instantiate the object. In other words Constructor injection uses parameters to inject dependencies.

Advantages
  • Construction Injection makes a strong dependency contract
  • Construction Injection supports testing, because dependencies can be passed in the constructor.
  • A dependency may be made immutable by making the dependency reference final by means that it prevents circular dependency.
Disadvantages
  • It requires up front wiring of the entire dependency graph.
The class that needs the Dependency must be exposing a public constructor that takes dependent class as constructor argument. In most cases, this should be the only one available constructor but if more than one Dependency is required then additional constructor arguments can be used.

Example

In this example "BusinessHelper" class's constructor takes an argument. Dependency inject from constructor argument.
  1. public class CommonClass  
  2. {  
  3.     //Implement common property and method.  
  4. }  
  5.   
  6. public class FirstObject : CommonClass  
  7. {  
  8.     public string GetData()  
  9.     {  
  10.         using (var helper = new BusinessHelper(this))  
  11.         {  
  12.             return helper.GetName();  
  13.         }  
  14.     }  
  15. }  
  16. public class BusinessHelper : IDisposable  
  17. {  
  18.     public BusinessHelper(CommonClass clsCommon) {}  
  19.     public string GetName()  
  20.     {  
  21.         return "Jignesh Test";  
  22.     }  
  23.   
  24.     public void Dispose()  
  25.     {  
  26.         // Dispose your object that out of scoped  
  27.     }  
  28. }  

Setter Injection

Setter Injection does not require the constructor to be changed but dependencies are passed through public properties that are exposed. Setter Injection allows us costly resources or services to be created as late as possible and only when required.

Setter Injection should be used carefully in place of Constructor Injection, because
  1. In Setter Injection does not have clear idea which dependencies are required when?
  2. It is very difficult to trace down when exceptions occurs. Which means it can save on modifying a lot of legacy code when introducing a new method.
Advantages
  • It does not require up front wiring of entire dependency graph.
Disadvantage
  • It is very difficult to identify which dependencies are required.
Example

In this example "BusinessHelper" class's constructor does not accept any arguments. Dependency injection from the setting property is called "clsCommon".
  1. public class CommonClass  
  2. {  
  3.     //Implement common property and method.  
  4. }  
  5.   
  6. public class FirstObject : CommonClass  
  7. {  
  8.     public string GetData()  
  9.     {  
  10.         using (var helper = new BusinessHelper())  
  11.         {  
  12.             helper.clsCommon = this;  
  13.             return helper.GetName();  
  14.         }  
  15.     }  
  16. }  
  17. public class BusinessHelper : IDisposable  
  18. {  
  19.     public CommonClass clsCommon { getset; }  
  20.     public BusinessHelper() { }  
  21.     public string GetName()  
  22.     {  
  23.         return "Jignesh Test";  
  24.     }  
  25.   
  26.     public void Dispose()  
  27.     {  
  28.         // Dispose your object that out of scoped  
  29.     }  
  30. }  

Interface Based Injection

Interface based Injection is implemented using common interfaces that other classes need to implement to inject dependencies. This type of injected from both the way either constructor injection or setter injection.

Benefits and drawbacks depend on which dependency injection is used with interface based injection.

Advantages of Dependency Injection pattern
The main advantage of DI is, it makes our code more reusable, maintainable, testable and readable.

No comments:

Post a Comment