Services that are registered as Transient are always different . That is, for each service call, a new instance of the object is created and provided to the DI .
Services that are registered as Scoped provide one object to the DI for each request .
Services that are registered as Singleton are provided to the DI in the first request of an object of the desired class , and in subsequent requests the same object is provided to the DI .
To show the difference in performance between these lifetimes, consider a simple interface that has a GUID property , and the class that inherits from this interface initializes the GUID property in its constructor . Here are three interfaces named IOperationTtansient , IOperationScoped and IOperationSingleton , each of which inherits from IOperation . Then we register all four interfaces with different lifetimes and the difference between these lifetimes will be shown.
public interface IOperation
{
Guid OperationId { get; }
}
public interface IOperationTransient : IOperation
{
}
public interface IOperationScoped : IOperation
{
}
public interface IOperationSingleton : IOperation
{
}
In the following, we will implement the class that inherited from these interfaces as follows
public class Operation : IOperationTransient, IOperationScoped, IOperationSingleton
{
Guid _guid;
public Operation()
{
_guid = Guid.NewGuid();
}
public Guid OperationId => _guid;
}
In the following , we will implement a class to show the difference between Scoped and Transient , which only receives services from the constructor and performs the initial value.
public class OperationService
{
public IOperationTransient TransientOperation { get; }
public IOperationScoped ScopedOperation { get; }
public IOperationSingleton SingletonOperation { get; }
public OperationService(IOperationTransient transientOperation,
IOperationScoped scopedOperation,
IOperationSingleton singletonOperation)
{
TransientOperation = transientOperation;
ScopedOperation = scopedOperation;
SingletonOperation = singletonOperation;
}
}
And then we register the classes in DI.
services.AddScoped<IOperationScoped, Operation>();
services.AddSingleton<IOperationSingleton, Operation>();
services.AddTransient<IOperationTransient, Operation>();
services.AddTransient<OperationService, OperationService>();
Then we receive the services in the controller via DI and in the view we show the GUID value .
public class HomeController : Controller
{
private readonly OperationService _operationService;
private readonly IOperationTransient _transientOperation;
private readonly IOperationScoped _scopedOperation;
private readonly IOperationSingleton _singletonOperation;
public HomeController(OperationService operationService, IOperationTransient transientOperation, IOperationScoped scopedOperation, IOperationSingleton singletonOperation)
{
_operationService = operationService;
_transientOperation = transientOperation;
_scopedOperation = scopedOperation;
_singletonOperation = singletonOperation;
}
public IActionResult Index()
{
ViewBag.Transient = _transientOperation;
ViewBag.Scoped = _scopedOperation;
ViewBag.Singleton = _singletonOperation;
ViewBag.Service = _operationService;
return View();
}
}
View code
@{
IOperationTransient operationTransient = (IOperationTransient)ViewBag.Transient;
IOperationScoped operationScoped = (IOperationScoped)ViewBag.Scoped;
IOperationSingleton operationSingleton = (IOperationSingleton)ViewBag.Singleton;
OperationService operationService = (OperationService)ViewBag.Service;
}
<div>
<p>Scoped : @operationScoped.OperationId</p>
<p>Transient : @operationTransient.OperationId</p>
<p>Singleton : @operationSingleton.OperationId</p>
</div>
<p>Operation Service</p>
<div>
<p>Scoped : @operationService.ScopedOperation.OperationId</p>
<p>Transient : @operationService.TransientOperation.OperationId</p>
<p>Singleton : @operationService.SingletonOperation.OperationId</p>
</div>
Finally, the following output will be shown in the view.
First request:
Scoped : cc0de4ac-0aaf-4e18-8a66-7c9672384f7b
Transient : 853f0faa-658e-4d9e-8288-99656636a96d
Singleton : 94e426e4-ec53-4665-949c-07eaf2f76dad
Operation Service
Scoped : cc0de4ac-0aaf-4e18-8a66-7c9672384f7b
Transient : 11e27e2e-1ecf-4fb7-b90f-6aace02121a4
Singleton : 94e426e4-ec53-4665-949c-07eaf2f76dad
Second request:
Scoped : d9f085f5-f72f-4eea-bf70-d490a602e80d
Transient : 11bab21a-032e-4eb5-8d5f-fd86ea19a640
Singleton : 94e426e4-ec53-4665-949c-07eaf2f76dad
Operation Service
Scoped : d9f085f5-f72f-4eea-bf70-d490a602e80d
Transient : 12f7a9a6-a38f-4abd-aef3-9cef25bb2732
Singleton : 94e426e4-ec53-4665-949c-07eaf2f76dad
The class that is registered as Singleton is initialized in the first request and shows the same value in subsequent requests .
But the class that is registered as Scoped type shows a new value for each request .
And in the class that is registered as Transient , it displays a new value for each class request .
In this example, each service is called twice via DI. Once in the controller and once in the OperationService class, but Scoped shows only one value per request, but Transient shows a new value for each call.
Powered by Froala Editor