Implementation of Dependency Injection Pattern

Implementation of Dependency Injection Pattern

29 Mar 2024
Intermediate
870K Views
10 min read
Learn via Video Course & by Doing Hands-on Labs

⭐ .NET Design Patterns Course: Design Patterns in C# Online Training

Dependency Injection Pattern in C#: An Overview

Dependency Injection (DI) is a software design pattern that allows us to develop loosely coupled code. DI is a great way to reduce tight coupling between software components. DI also enables us to better manage future changes and other complexities in our software. The purpose of DI is to make code maintainable.

The Dependency Injection pattern uses a builder object to initialize objects and provide the required dependencies to the object means it allows you to "inject" a dependency from outside the class.

For example, Suppose your Client class needs to use two service classes, then the best you can do is to make your Client class aware of abstraction i.e. IService interface rather than implementation i.e. Service1 and Service2 classes. In this way, you can change the implementation of the IService interface at any time (and for how many times you want) without changing the client class code.

 Dependency Injection pattern

We can modify this code by following the Dependency Injection implementation ways. We have the following different ways to implement Dependency Injection :

Constructor Injection

  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. The injected component can be used anywhere within the class.

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

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

public interface IService {
 void Serve();
}
public class Service1 : IService {
 public void Serve() { 
 Console.WriteLine("Service1 Called"); 
 }
}
public class Service2 : IService {
 public void Serve() { 
 Console.WriteLine("Service2 Called"); 
 }
}
public class Client {
 private IService _service;
 public Client(IService service) {
 this._service = service;
 }
 public ServeMethod() { 
 this._service.Serve(); 
 }
}
class Program
{
 static void Main(string[] args)
 {
 //creating object
 Service1 s1 = new Service1(); 
 //passing dependency
 Client c1 = new Client(s1);
 //TO DO:
 c1.ServeMethod();
 
 Service2 s2 = new Service2(); 
 //passing dependency
 c1 = new Client(s2);
 //TO DO:
 c1.ServeMethod();
 }
}

The Injection happens in the constructor, bypassing the Service that implements the IService Interface. The dependencies are assembled by a "Builder" and the Builder's responsibilities are as follows:

  1. Knowing the types of each IService

  2. According to the request, feed the abstract IService to the Client

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.

public interface IService {
 void Serve();
}
public class Service1 : IService {
 public void Serve() { 
 Console.WriteLine("Service1 Called"); 
 }
}
public class Service2 : IService {
 public void Serve() { 
 Console.WriteLine("Service2 Called"); 
 }
}
public class Client {
 private IService _service;
 public IService Service {
 set { this._service = value; }
 }
 public ServeMethod() { 
 this._service.Serve(); 
 }
}
class Program
{
 static void Main(string[] args)
 {
 //creating object
 Service1 s1 = new Service1(); 
 
 Client client = new Client();
 client.Service = s1; //passing dependency
 //TO DO:
 client.ServeMethod();

 Service2 s2 = new Service2(); 
 client.Service = s2; //passing dependency
 //TO DO:
 client.ServeMethod();
 }
}

Method Injection

  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.

public interface IService {
 void Serve();
}
public class Service1 : IService {
 public void Serve() { 
 Console.WriteLine("Service1 Called"); 
 }
}
public class Service2 : IService {
 public void Serve() { 
 Console.WriteLine("Service2 Called"); 
 }
}
public class Client {
 public void ServeMethod(IService service) {
 service.Serve();
 }
}
class Program
{
 static void Main(string[] args)
 {
 //creating object
 Service1 s1 = new Service1(); 
 
 Client client = new Client(); 
 client.Start(s1); //passing dependency
 //TO DO:
 client.ServeMethod();

 Service2 s2 = new Service2(); 
 client.Start(s2); //passing dependency
 client.ServeMethod();
 }
}

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 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 a DI container,

What do you think?

I hope you will enjoy the various ways of implementing DI patterns. Learn more about it through our Dependency Injection Tutorial. I would like to have feedback from my blog readers. Your valuable feedback, questions, or comments about this article are always welcome. Enjoy Coding..!

FAQs

Q1. How do you inject a dependency in C#?

By supplying the DEPENDENCY through the class's constructor when creating the instance of that class.

Q2. Which design pattern is used in dependency injection?

 Factory Pattern, Template Method Design Pattern, Strategy Pattern and Service Locator pattern too

Q3. Which principle is an implementation of dependency injection?

The dependency inversion principle
Share Article
Batches Schedule
About Author
Shailendra Chauhan (Microsoft MVP, Founder & CEO at Scholarhat by DotNetTricks)

Shailendra Chauhan is the Founder and CEO at ScholarHat by DotNetTricks which is a brand when it comes to e-Learning. He provides training and consultation over an array of technologies like Cloud, .NET, Angular, React, Node, Microservices, Containers and Mobile Apps development. He has been awarded Microsoft MVP 8th time in a row (2016-2023). He has changed many lives with his writings and unique training programs. He has a number of most sought-after books to his name which has helped job aspirants in cracking tough interviews with ease.
Accept cookies & close this