I want to implement dependency injection (DI) in ASP.NET Core. So after adding this code to ConfigureServices
method, both ways work.
What is the difference between the services.AddTransient
and service.AddScoped
methods in ASP.NET Core?
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddScoped<IEmailSender, AuthMessageSender>();
}
This question is related to
c#
asp.net-core
.net-core
Normally the code request should be made through a constructor parameter, as in
public MyConsumingClass(IDependency dependency)
I wanted to point out in @akazemis's answer that "services" in the context of DI does not imply RESTful services; services are implementations of dependencies that provide functionality.
Transient, scoped and singleton define object creation process in ASP.NET MVC core DI when multiple objects of the same type have to be injected. In case you are new to dependency injection you can see this DI IoC video.
You can see the below controller code in which I have requested two instances of "IDal" in the constructor. Transient, Scoped and Singleton define if the same instance will be injected in "_dal" and "_dal1" or different.
public class CustomerController : Controller
{
IDal dal = null;
public CustomerController(IDal _dal,
IDal _dal1)
{
dal = _dal;
// DI of MVC core
// inversion of control
}
}
Transient: In transient, new object instances will be injected in a single request and response. Below is a snapshot image where I displayed GUID values.
Scoped: In scoped, the same object instance will be injected in a single request and response.
Singleton: In singleton, the same object will be injected across all requests and responses. In this case one global instance of the object will be created.
Below is a simple diagram which explains the above fundamental visually.
The above image was drawn by the SBSS team when I was taking ASP.NET MVC training in Mumbai. A big thanks goes to the SBSS team for creating the above image.
AddSingleton() creates a single instance of the service when it is first requested and reuses that same instance in all the places where that service is needed.
In a scoped service, with every HTTP request, we get a new instance. However, within the same HTTP request, if the service is required in multiple places, like in the view and in the controller, then the same instance is provided for the entire scope of that HTTP request. But every new HTTP request will get a new instance of the service.
With a transient service, a new instance is provided every time a service instance is requested whether it is in the scope of the same HTTP request or across different HTTP requests.
Transient
Scoped
Singleton
Use Singletons where you need to maintain application wide state. Application configuration or parameters, Logging Service, caching of data is some of the examples where you can use singletons.
After looking for an answer for this question I found a brilliant explanation with an example that I would like to share with you.
You can watch a video that demonstrate the differences HERE
In this example we have this given code:
public interface IEmployeeRepository
{
IEnumerable<Employee> GetAllEmployees();
Employee Add(Employee employee);
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
public class MockEmployeeRepository : IEmployeeRepository
{
private List<Employee> _employeeList;
public MockEmployeeRepository()
{
_employeeList = new List<Employee>()
{
new Employee() { Id = 1, Name = "Mary" },
new Employee() { Id = 2, Name = "John" },
new Employee() { Id = 3, Name = "Sam" },
};
}
public Employee Add(Employee employee)
{
employee.Id = _employeeList.Max(e => e.Id) + 1;
_employeeList.Add(employee);
return employee;
}
public IEnumerable<Employee> GetAllEmployees()
{
return _employeeList;
}
}
HomeController
public class HomeController : Controller
{
private IEmployeeRepository _employeeRepository;
public HomeController(IEmployeeRepository employeeRepository)
{
_employeeRepository = employeeRepository;
}
[HttpGet]
public ViewResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(Employee employee)
{
if (ModelState.IsValid)
{
Employee newEmployee = _employeeRepository.Add(employee);
}
return View();
}
}
Create View
@model Employee
@inject IEmployeeRepository empRepository
<form asp-controller="home" asp-action="create" method="post">
<div>
<label asp-for="Name"></label>
<div>
<input asp-for="Name">
</div>
</div>
<div>
<button type="submit">Create</button>
</div>
<div>
Total Employees Count = @empRepository.GetAllEmployees().Count().ToString()
</div>
</form>
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IEmployeeRepository, MockEmployeeRepository>();
}
Copy-paste this code and press on the create button in the view and switch between
AddSingleton
, AddScoped
and AddTransient
you will get each time a different result that will might help you understand this.
AddSingleton() - As the name implies, AddSingleton() method creates a Singleton service. A Singleton service is created when it is first requested. This same instance is then used by all the subsequent requests. So in general, a Singleton service is created only one time per application and that single instance is used throughout the application life time.
AddTransient() - This method creates a Transient service. A new instance of a Transient service is created each time it is requested.
AddScoped() - This method creates a Scoped service. A new instance of a Scoped service is created once per request within the scope. For example, in a web application it creates 1 instance per each http request but uses the same instance in the other calls within that same web request.
In .NET's dependency injection there are three major lifetimes:
Singleton which creates a single instance throughout the application. It creates the instance for the first time and reuses the same object in the all calls.
Scoped lifetime services are created once per request within the scope. It is equivalent to a singleton in the current scope. For example, in MVC it creates one instance for each HTTP request, but it uses the same instance in the other calls within the same web request.
Transient lifetime services are created each time they are requested. This lifetime works best for lightweight, stateless services.
Here you can find and examples to see the difference:
ASP.NET 5 MVC6 Dependency Injection in 6 Steps (web archive link due to dead link)
Your Dependency Injection ready ASP.NET : ASP.NET 5
And this is the link to the official documentation:
Source: Stackoverflow.com