
Introducing Dependency Injection in .NET
dependency injection
2 Articles
In this article, let's learn about Dependency Injection
in .NET.
Table of Contents
- Introduction
- What is Dependency?
- Dependency Injection visualization
- Working with Dependency Injection
- Phases of Dependency Injection
- Advantages
- Summary
Introduction
.NET supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. Dependency injection in .NET is a built-in part of the framework.
What is Dependency?
A dependency is an object that another object depends on. Examine the following ClassB
class with
that other classes depend on:
Code Sample - Dependency Injection Demo
A class can create an instance of the ClassB
class to make use of it. In the following example, the
ClassB
class is a dependency of the ClassA
class:
Code Sample - Dependency Injection Demo
The class creates and directly depends on the ClassB
class. Hard-coded dependencies, such as in the previous
example, are problematic and should be avoided for the following reasons:
- To replace
ClassB
with a different implementation, theClassA
class must be modified. -
If
ClassB
has dependencies, they must also be configured by theClassA
class. In a large project with multiple classes depending onClassB
, the configuration code becomes scattered across the app. -
This implementation is difficult to unit test. The app should use a mock or stub
ClassB
class, which isn't possible with this approach.
So let's try to get the instance of ClassB
from constructor of ClassA
.
Code Sample - Dependency Injection Demo
Here is the complete wire up in Program.cs
.
Code Sample - Before Dependency Injection
Dependency injection addresses these problems through:
- The use of an interface or base class to abstract the dependency implementation.
-
Registration of the dependency in a service container. .NET provides a built-in service container,
IServiceProvider
. Services are typically registered at the app's start-up and appended to anIServiceCollection
. Once all services are added, you useBuildServiceProvider
to create the service container. - Injection of the service into the constructor of the class where it's used. The framework takes on the responsibility of creating an instance of the dependency and disposing of it when it's no longer needed.
Code Sample - After Dependency Injection
Dependency Injection visualization
DI enables decoupling and supports development of loosely-coupled code. DI supports implementation of
two related concepts, inversion of control
and the dependency inversion principle
.
Inversion of Control
- - High-level modules should not depend on low-level modules.
Dependency Inversion Principle
- - A framework controls which code is executed next, not your code.

Working with Dependency Injection
DI Configuration consist of two main phases, Registration phase and Resolving Phase.
Steps
- Install
Microsoft.Extensions.Hosting
Nuget Package. Register services using
Code Sample - Registering Services
- Resolve services using
Host.Services.GetRequiredService<YourService>();

Phases of Dependency Injection
Registration Phase
Register types in container so it knows of their existence and when to construct them.
- Register types for later use.
- Indirection through service type and implementing type.
- Choose a lifetime.
Registering Types
When registering types you specify the lifetime, the requested service type and the implementing type. If these types are the same you provide it once.
Code Sample - Registering Types
Resolving Phase
Container is responsible for instantiating types and providing them when requested.
- Resolves and creates types directly.
- Provides dependencies of types you work with.
- Provides dependencies to dependencies of the types you work with.
- Manage the lifetimes of the types.
Resolving Types
When resolving a type, you request an instance of service type. The container will find the implementing type, instantiate it if needed, and return it to you.
If the implementing type has dependencies, they are provided to the implementing type as well.
Code Sample - Resolving Types

Advantages
- No longer calling constructors.
- Container calls the constructors.
- Not concerned with ordering registrations.
- Not concerned with dependencies of each type.
Summary
In this article, we learn't what is Dependency Injection
in .NET. We understood how classes are invoked in
traditional flow using new()
keyword and how dependency injection helped us to avoid the
new()
glue and makes it easy to manage dependencies. In next article lets talk about
lifetimes in dependency injection in .NET.