How to use dependency injection in .NET
Dependency injection (DI) is a technique for achieving loose coupling between objects and their collaborators, or dependencies. Rather than directly instantiating collaborators, or using static references, the objects you want to work with are provided to you at runtime. This article explains what DI is, why it's beneficial, and how to use it in .NET applications.
Consider the following example:
In this example, the Car class creates its own Engine and GasTank objects in its constructor. This means that it is tightly coupled to those classes and cannot easily use different implementations or mock objects for testing.
Using DI, we would rewrite the Car class as follows:
In this example, the Car class expects an Engine and a GasTank object to be passed to its constructor. This means that it is loosely coupled to those classes and can use any implementation or mock object that implements their interfaces.
Why use dependency injection?
- It reduces the coupling between your classes and their dependencies. This makes your code more modular, reusable, and testable.
- It improves the separation of concerns in your code. Each class only focuses on its own behavior and relies on its dependencies to provide any other functionality.
- It makes your code more flexible and extensible. You can easily change or add new dependencies without modifying your existing classes.
- It enables you to use inversion of control (IoC) containers. These are frameworks that can automatically provide your classes with their dependencies at runtime based on some configuration rules.
How to use dependency injection in .NET
There are two main ways to implement DI in .NET: using the built-in DI container that comes with ASP.NET Core or using a third-party DI container that works with .NET.
Using the built-in DI container
The built-in DI container is provided by the Microsoft.Extensions.DependencyInjection namespace and is part of the ASP.NET Core framework. It supports constructor injection, property injection, and method injection. It also supports various lifetimes for your services: singleton, scoped, transient, or custom.
To use the built-in DI container, you need to do the following steps:
- Define your services and their dependencies using interfaces.
- Register your services with the DI container in the Startup class.
- Inject your services into your classes using constructors, properties, or methods.
For example, suppose we have a simple web application that uses a GreetingService to generate greetings based on the current time of day. The GreetingService depends on an ITimeService that provides the current time.
We would define our services as follows:
We would register our services with the DI container in the Startup class as follows:
We would inject our services into our classes using constructors as follows:
Now, when we send a GET request to /greeting, we will get a response based on the current time of day.
Using a third-party DI container
There are many third-party DI containers available for .NET, such as Autofac, Ninject, StructureMap, Unity, etc. They offer different features and capabilities than the built-in DI container, such as auto-registration, interception, decorators, etc.
To use a third-party DI container, you need to do the following steps:
- Install the NuGet package for the DI container of your choice.
- Define your services and their dependencies using interfaces.
- Configure your services with the DI container using its specific syntax and conventions.
- Use an adapter or extension method to integrate the DI container with ASP.NET Core.
For example, suppose we want to use Autofac as our DI container instead of the built-in one. We would do the following steps:
- Install the Autofac.Extensions.DependencyInjection NuGet package.
- Define our services as before.
- Configure our services with Autofac using a ContainerBuilder object and its fluent API.
- Use the UseServiceProviderFactory method to integrate Autofac with ASP.NET Core.
We would configure our services with Autofac as follows:
Top comments (0)