Dependency Injection Explained in .Net Core

Hitesh Kachave
ashsoftware
Published in
5 min readOct 22, 2019
Source: https://www.wikipedia.org

Overview
This article explains Service Lifetime for dependency injection in .Net Core. Familiarity with DI and the basics of .Net core is needed for a better understanding of this article.

What is Dependency Injection (DI)?
DI is a software design pattern. It allows us to develop loosely coupled code. The purpose of the DI is to make your code more maintainable and testable.

There are three different ways to implement DI
1. Constructor Injection
2. Property Injection
3. Method Injection

That’s it for the basics of DI. Let’s start with the topic of this article -

Service Lifetime for Dependency Injection(.Net Core)
There are three types of services in dependency injection as follows -

1. Transient:
Transient service is created every time whenever requested. The transient service works best for lightweight stateless service.
2. Scoped:
Scoped service is created once per request and that instance is used within the same request scope. For different requests, the new instance is created.
3. Singleton:
Singleton service is created only once per application. All subsequent requests use the same instance i.e any new request does not create a new instance, it uses the existing instance. The instance is released when you end of the application.

Let’s understand the Transient, Scoped and Singleton using a simple demo using .Net Core Web API 2.0.

Demo

Create a sample project and select .Net Core Web API 2.0. Now let’s discuss each service lifetime in details -

1. Transient:
a. Create an interface with a simple method that returns string.

b. Create the service and implement the interface(ITransient.cs). In the GetValue() method return unique id as a string.

c. Now it’s time to register the service. To register the service, go to Startup.cs class and register the service (Transient.cs) under the ConfigureServices method -

d. Open the controller (ValuesController.cs) and inject the dependency.

Here, I have injected two instances of Transient service into the controller. Now run the application and see the output.

e. Run
http://localhost:59895/api/values

[
“Transient 1: db895935–7813–480d-a86a-44c10eb5cd0f”,
“Transient 2: e4e9e5c6-ab22–4968-a379-e665fc533d5c”
]

See the above output there is two different unique id it means the new instance is created for each request.

2. Scoped:

For scoped I have changed the approach to explain to you properly, Let’s create .Net Core Console App.

a. Create an interface with a simple method that returns string.

b. Create the service and implement the interface (IScoped.cs). In the GetValue() method return unique id as a string.

c. Let’s open the Program.cs file. Inject the dependency and call the GetValue() method.

In the above code, I have registered the dependency and as you can see in the above code I have created the scope using the CreateScope() method. Let’s run the code and see the output.

d. Run

See the above output for the “scoped 1” unique id is generated and for the “Same Scoped 1” and “Same Scoped 2” both the ids are the same. It means the same instance is used within the same request scope.

3. Singleton:

a. Create an interface with a simple method that returns string.

b. Create the service and implement the interface (ISingleton.cs). In the GetValue() method return unique id as a string.

c. Now it’s time to register the service. To register the service, go to Startup.cs class and register the service (Singleton.cs) under the ConfigureServices method.

d. Open the controller (ValuesController.cs) and inject the dependency.

Here, I have created two instances for Singleton service and injected into the controller. Now run the application and see the output.

e. Run

http://localhost:59895/api/values

[

“Singleton 1: ff2774d8–4ab9–457e-8a05–571382123797”,

“Singleton 2: ff2774d8–4ab9–457e-8a05–571382123797”

]

See above output the same unique id is used, it means only one instance is created for each request.

Best Practice

  • Transient Service, you should use transient service for the lightweight service. It’s simple to design transient services. You generally don’t care about multi-threading and memory leaks and you know the service has a short life.
  • Scoped Service, it is a better option to use this service when you want to maintain the state within a request.
  • Singleton Service, when you want to maintain the application-wide state you can use singleton service. But it will deal with multi-threading and potential memory leak problems. you can use singleton service for logging service, to caching of the data and so on.

Summary

In this article, we learned about the service lifetime for dependency injection.

--

--