Friday, June 25, 2021

What is Dependency Injection C#? How It Works, Types of Dependency Injections in C#

Dependency Injection (DI) is a software design pattern. Dependency Injection reduces the hard-coded dependencies among your classes by injecting those dependencies at run time instead of design time technically.

 If you take a closer look at Dependency Injection (DI), it is a software design pattern which enables the development of loosely coupled code. Through DI, you can decrease tight coupling between software components. It is also known as Inversion-of-Control, which makes unit testing convenient.

Dependency Injection reduces the hard-coded dependencies among your classes by injecting those dependencies at run time instead of design time technically.

It is critical to take a step back to the basics of designing an object-oriented application where a major facet of design is “loose coupling.” This means that objects only have as many dependencies as needed to do their jobs–and, the number of dependencies should be limited.

This article explains how to implement Dependency Injection in C# and .NET code. 

We have the following ways to implement Dependency Injection. 

1.       Constructor Injection

2.       Setter Injection

3.       Method Injection

Since DI is utilized to make code maintainable, it uses a pattern with a builder object to initialize objects and give the required dependencies to the object. As you can see, you can now “inject” a dependency from outside the class.

How Dependency Injection C# Works

To illustrate, if your Client class needs to use a Service class component, the most you can do is make your Client aware of an IService interface instead of a Service class. Through this execution, you get to change the implementation of the Service class as many times as you like without breaking the host code.

It is helpful to understand the Dependency Inversion Principle, which gives us the guidelines for writing loosely-coupled classes. Here is the definition:

Ø  High-level modules should not depend on low-level modules. Both should depend on abstractions.

Ø  Abstractions should not depend upon details. Details should depend upon abstractions.

How do you get two modules to depend on each other? Through Inversion of control. This is the actual mechanism you can use to make higher-level modules that depend on abstractions. You must invert the control to follow the dependency inversion principle. As a result, your high-level modules are no longer dependent on the lower-level concrete implementations.

Let’s dive a bit deeper into the three types of Dependency Injections:

Constructor Injection in C#:

1.      This is a widely used way to implement DI.

2.   Dependency Injection is done by supplying the DEPENDENCY through the class’s constructor when creating the instance of that class.

3.      Injected component can be used anywhere within the class.

4.       Recommended to use when the injected dependency, you are using across the class methods.

5.       It addresses the most common scenario where a class requires one or more dependencies. 

We can use the injection component anywhere within the class. It addresses the most common scenario where a class requires one or more dependencies. The following is an example:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6.   
  7. namespace propertyinjuction  
  8. {  
  9.     public interface text  
  10.     {
  11.         void print();
  12.     }
  13.     class format : text
  14.     {
  15.         public void print()
  16.         {
  17.             Console.WriteLine(" here is text format");
  18.         }      
  19.     }
  20.     // constructor injection
  21.     public class constructorinjection
  22.     {  
  23.         private text _text;
  24.         public constructorinjection(text t1)
  25.         {
  26.             this._text = t1;          
  27.         }
  28.         public void print()
  29.         {  
  30.             _text.print();
  31.         }
  32.     }
  33.     class constructor
  34.     {  
  35.         static void Main(string[] args)
  36.         {  
  37.             constructorinjection cs = new constructorinjection(new format());
  38.             cs.print();
  39.             Console.ReadKey();          
  40.         }
  41.     }
  42. }

By passing the services that implemented the text interface the builder assembled the dependencies.

 Property/Setter Injection:

1.       Recommended using when a class has optional dependencies, or where the implementations may need to be swapped.

2.       Different logger implementations could be used in this way.

3.       Does not require the creation of a new object or modifying the existing one. Without changing the object state, it could work.

 We use constructor injection, but there are some cases where I need a parameter-less constructor, so we need to use property injection.  The following is an example:

  1. public interface INofificationAction
  2. {      
  3.    void ActOnNotification(string message);
  4. }
  5.    class atul     {  
  6.        INofificationAction task = null;
  7.        public void notify(INofificationAction  at ,string messages)
  8.        {  
  9.        this.task = at;
  10.        task.ActOnNotification(messages);    
  11.        }     
  12.    }
  13.    class EventLogWriter : INofificationAction
  14.    {
  15.        public void ActOnNotification(string message)
  16.        {
  17.            // Write to event log here
  18.        }
  19.    }
  20.    class Program
  21.    {
  22.        static void Main(string[] args)
  23.        {
  24.            //services srv = new services();
  25.            //other oth = new other();
  26.            //oth.run();
  27.            //Console.WriteLine();
  28.            EventLogWriter elw = new EventLogWriter();
  29.            atul at = new atul();
  30.            at.notify(elw, "to logg");
  31.            Console.ReadKey();
  32.        }
  33.    }

You cannot control when the dependency is set at all, it can be changed at any point in the object's lifetime. 

Method Injection in C#:

  1.       Inject the dependency into a single method and generally for the use of that method.

2.       It could be useful, where the whole class does not need the dependency, only one method having that dependency.

3.       This is the way is rarely used.

 The following is an example:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.   
  7. namespace propertyinjuction
  8. {  
  9.     public interface Iset
  10.     {
  11.         void print();      
  12.     }
  13.     public class servic : Iset
  14.     {
  15.         public void print()
  16.         {  
  17.             Console.WriteLine("print........");          
  18.         }      
  19.     }
  20.     public class client
  21.     {
  22.         private Iset _set;
  23.         public void run(Iset serv)
  24.         {  
  25.             this._set = serv;
  26.             Console.WriteLine("start");
  27.             this._set.print();
  28.         }      
  29.     }
  30.     class method
  31.     {
  32.         public static void Main()
  33.         {
  34.             client cn = new client();
  35.             cn.run(new servic());
  36.             Console.ReadKey();         
  37.         }
  38.     }
  39. }

Advantages of Dependency Injection

1.       Reduces class coupling

2.       Increases code reusability

3.       Improves code maintainability

4.       Make unit testing possible

DI Container

The recommended way to implement DI is, you should use DI containers. If you compose an application without a DI CONTAINER, it is like a POOR MAN’S DI. If you want to implement DI within your ASP.NET MVC application using DI container, please do refer Dependency Injection in ASP.NET MVC using Unity IoC Container.

 Summary: 

This article helps to reduces class coupling, increase code reuse, improve code maintainability, improve application testing and help to easily do unit testing. In this article with code samples, we saw some use cases of dependency injection using C# and .NET.

 

Popular Posts