Showing posts with label design pattern. Show all posts
Showing posts with label design pattern. Show all posts

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.

Singleton design pattern

Singleton design pattern is all about ensuring that a class has only one instance in the application. It is a design pattern from Creational Pattern of Gang of Four (GOF) Design Patterns.
In this pattern, we have to restrict creating the instance if it is already created and use the existing one.
First of all, we have to make our class constructor as a private so that we can not create object from outside of the class using the new keyword.
We have many approaches to use singleton design pattern in C#. Here, we are going through a few of them.
Let’s start with the example for better understanding.
We are using console application for this example and we are going to take Employee class and will use a private constructor.
First approach 
  1. public class Employee  
  2. {  
  3.     private static Employee instance = null;  
  4.     private Employee() {}  
  5.     public static Employee GetInstance {  
  6.         get {  
  7.             if (instance == null) {  
  8.                 instance = new Employee();  
  9.             }  
  10.             return instance;  
  11.         }  
  12.     }  
  13. }   
In the code given above, we are using a static property named as Instance for getting the instance outside of the class without using its object; and inside this property, we are checking if the instance is already created or not. If it is first time request, then we are creating an instance. We can also use method instead of property as below.
  1. public static Employee GetInstance()  
  2. {  
  3.     if (instance == null) {  
  4.         instance = new Employee();  
  5.     }  
  6.     return instance;  
  7. }   
So now, Employee class has only one constructor which is private so we can’t create instance using new keyword outside of the class

C#
And also, we can’t inherit this class into another class because of a private constructor.

C#
Now, we can use instance property many times and will check the instances are same or not as below. 
  1. static void Main(string[] args)  
  2. {  
  3.     Employee emp1 = Employee.GetInstance;  
  4.     Employee emp2 = Employee.GetInstance;  
  5.     if (emp1 == emp2) {  
  6.         Console.WriteLine("Same instances");  
  7.     } else {  
  8.         Console.WriteLine("Different instances");  
  9.     }  
  10.     Console.ReadLine();  
  11. }   
Output

C#
The first approach is good but it is not thread safe. Let's assume that first time two different threads will evaluate the if condition at the same time for checking if the instance is null or not, and for both the cases, it will return true because till now no instance is created. So, both threads will enter into the if condition and create new instances. It is a violation of singleton design pattern.
To overcome this situation, we have to write threads safety program as below.
Second approach 
  1. public class Employee {  
  2.     private static Employee instance = null;  
  3.     private static readonly object instanceLock = new object();  
  4.     private Employee() {}  
  5.     public static Employee GetInstance {  
  6.         get {  
  7.             lock(instanceLock) {  
  8.                 if (instance == null) {  
  9.                     instance = new Employee();  
  10.                 }  
  11.                 return instance;  
  12.             }  
  13.         }  
  14.     }  
  15. }   
This approach is thread safe because at one time, only one thread can enter inside the lock block. Multiple threads can not access GetInstance at the same time that means it is a slow approach.
To overcome this situation, we have to write double-check locking program as below.
Third approach 
  1. public class Employee  
  2. {  
  3.     private static Employee instance = null;  
  4.     private static readonly object instanceLock = new object();  
  5.     private Employee() {}  
  6.     public static Employee GetInstance {  
  7.         get {  
  8.             if (instance == null) {  
  9.                 lock(instanceLock) {  
  10.                     if (instance == null) {  
  11.                         instance = new Employee();  
  12.                     }  
  13.                 }  
  14.             }  
  15.             return instance;  
  16.         }  
  17.     }  
  18. }   
In this approach, firstly we are checking if (instance == null ) every time hence after creating an instance of the class first time. So, from second time onwards, it will not go inside of the first if block and return existing instance, but in the case of very first time, suppose two threads will come at the same time to access first if statement and get true value and enter into the if block, then also, only one thread can enter into the lock statement and wait for other thread to complete task.
So, after completion of the task of first thread, when the second thread will enter inside the lock block it will check again if(instance==null); and at this time, we already have instance which is created by first thread, so it will not allow inside the second if block and will return existing instance.
We are going to see the same thing without using if condition or lock in our next approach.
Fourth approach 
  1. public class Employee  
  2. {  
  3.     private static readonly Employee instance = new Employee();  
  4.     private Employee() {}  
  5.     public static Employee GetInstance {  
  6.         get {  
  7.             return instance;  
  8.         }  
  9.     }  
  10. }   
This is very simple and thread safe approach. It is called as Static initialization or Early instance creation. Singleton Design pattern is very useful for the logger implementation in our application and this is the famous design pattern.
In this article, we have covered the basic understanding of Singleton design pattern.