Dependency Injection (DI) is a design pattern to enhance the modularity and maintainability of software systems, it facilitates the management of dependencies between objects. In this blog we will deep dive into Dependency Injection and how you can implement it in C# with clear examples.

What is Dependency Injection?

The primary purpose of Dependency Injection is to decouple the object creation from the object (client) that uses them. It involves supplying an object (a client) with its dependencies (services or objects that it uses) externally instead of creating them directly inside the class.

Let’s take an example to understand how dependency helps modularity and easier testing.

Example for Dependency Injection Design Pattern:

Let’s take an example of designing a logging system that writes input string into a File, we want to make it more flexible so that it can be further extended to log input string in Database, Event or Console etc without making any further changes to the main logic.

Without using Dependency Injection in C#:

In the above example we haven’t used any dependency injection concept at all, when we run the above code then it generates below output.

No_Dependency_Injection_Output_1.0
No_Dependency_Injection_Output_1.0
  • In the above sample code, LoggingService is tightly coupled with the FileLogger.

  • This piece of code is very hard to extend, if we want to implement DBLogging or EventLogging then LoggingService class would need a change to accommodate it.
  • Testing this piece code will also be a challenge since its tightly coupled with FileLogging, it will be hard to test for other test scenarios.
Using Dependency Injection in C#:

Let’s rewrite above scenario using Dependency Injection concept.

When we run the above code then it generates below output.

Dependency_Injection_Output_2.0
Dependency_Injection_Output_2.0
  • In this example, LoggingService is not tightly coupled, we are able to inject FileLogging and DbLogging through the constructor.

  • We can also extend this to inject any new Logging mode, like Event or Console logging from Client without making any modification to the LoggingService class.

Types of Dependency Injection

There are three ways of injecting dependencies:

  • Constructor Injection: The dependencies are injected through the class constructor.
  • Property Injection: The dependencies are set through the public properties of the class.
  • Method Injection: The dependencies are injected through the parameters of the class methods.

Constructor Injection:

Constructor injection is where the required dependencies are injected through the constructor, In the above example constructor LoggingService(ILogging logging) is used to inject the dependencies. Let’s check below code snippet for same.

Example – 1:

Property Injection 

Property injection involves public properties used to inject dependencies.

Example – 2:

  • In the above code sample, public property LoggingServiceInject { get; set; } is used to inject the dependencies.

  • From the Main method we are accessing the public property and setting the FileLogger and DbLogger dependencies as follows.

Method Injection:

Method injection is where the dependency is provided as a parameter to the method that requires it.

Example – 3:

  • In the above code sample, method LogMessage(string message, ILogging _LoggingService) is used to inject the dependencies.

  • From the Main method we are accessing the method and injecting the instance of FileLogger and DbLogger dependencies as follows.

Benefits of Dependency Injection?

Dependency Injection comes with several benefits:

  • Decoupling: This decoupling enhances the flexibility to change dependencies without modifying the classes that use them.
  • Ease of Testing: It’s easier to replace implementations with mock objects that simplifies unit testing.
  • Code Maintainability: By separating concerns, the code becomes easier to understand and maintain.
  • Flexibility and Scalability: You can change the implementation of a dependency without changing the classes that use it.

Conclusion

Dependency Injection in C# provides a clean separation of concerns where components are easily manageable, testable, and maintainable. This helps to create more modular applications and reduce the dependencies among application components.

Thanks for checking this out 🙂 please visit some of the other blogs design pattern.

ASP.NET MVC Pattern as Web Development

MVC Design Pattern