Quelle est la différence entre les services.AddTransient, service.AddScoped et service.Méthodes AddSingleton dans ASP.NET noyau?
Je veux mettre en œuvre injection de dépendance dans Asp.Net Base. Donc, après avoir ajouté ces codes à la méthodeConfigureServices , les deux méthodes fonctionnent.
Quelle est la différence entre les services .AddTransient et service.Les méthodes AddScope sont Asp.Net noyau?
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddScoped<IEmailSender, AuthMessageSender>();
}
4 réponses
Pour plus de précisions, cet exemple de asp.net docs montre la différence :
Pour démontrer la différence entre ces options de durée de vie et d'enregistrement, considérons une interface simple qui représente une ou plusieurs tâches comme une opération avec un identifiant unique, OperationId
. Selon la façon dont nous configurons La durée de vie de ce service, le conteneur fournira les mêmes instances ou des instances différentes du service à la classe requérante. Pour le rendre clair ce qui la durée de vie est demandée, nous allons créer un type par option de durée de vie:
using System;
namespace DependencyInjectionSample.Interfaces
{
public interface IOperation
{
Guid OperationId { get; }
}
public interface IOperationTransient : IOperation
{
}
public interface IOperationScoped : IOperation
{
}
public interface IOperationSingleton : IOperation
{
}
public interface IOperationSingletonInstance : IOperation
{
}
}
Nous implémentons ces interfaces en utilisant une seule classe, Operation
, qui accepte un Guid
dans son constructeur, ou utilise un nouveau Guid
si aucun n'est fourni.
Ensuite, dans ConfigureServices
, chaque type est ajouté au conteneur en fonction de sa durée de vie nommée:
services.AddTransient<IOperationTransient, Operation>();
services.AddScoped<IOperationScoped, Operation>();
services.AddSingleton<IOperationSingleton, Operation>();
services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));
services.AddTransient<OperationService, OperationService>();
Notez que le service IOperationSingletonInstance
utilise une instance spécifique avec un ID connu de Guid.Empty
donc il sera clair quand ce type est utilisé. Nous avons également enregistré un {[11] } qui dépend de chacun des autres types Operation
, de sorte qu'il sera clair dans une requête si ce service obtient la même instance que le contrôleur, ou une nouvelle, pour chaque type d'opération. Tout ce service expose ses dépendances en tant que propriétés, de sorte qu'elles peuvent être affichées dans la vue.
using DependencyInjectionSample.Interfaces;
namespace DependencyInjectionSample.Services
{
public class OperationService
{
public IOperationTransient TransientOperation { get; }
public IOperationScoped ScopedOperation { get; }
public IOperationSingleton SingletonOperation { get; }
public IOperationSingletonInstance SingletonInstanceOperation { get; }
public OperationService(IOperationTransient transientOperation,
IOperationScoped scopedOperation,
IOperationSingleton singletonOperation,
IOperationSingletonInstance instanceOperation)
{
TransientOperation = transientOperation;
ScopedOperation = scopedOperation;
SingletonOperation = singletonOperation;
SingletonInstanceOperation = instanceOperation;
}
}
}
Pour démontrer les durées de vie des objets dans et entre des requêtes individuelles distinctes à l'application, l'exemple comprend un OperationsController
qui demande chaque type de type IOperation
ainsi qu'un OperationService
. L'action Index
affiche ensuite toutes les valeurs OperationId
du contrôleur et du service.
using DependencyInjectionSample.Interfaces;
using DependencyInjectionSample.Services;
using Microsoft.AspNetCore.Mvc;
namespace DependencyInjectionSample.Controllers
{
public class OperationsController : Controller
{
private readonly OperationService _operationService;
private readonly IOperationTransient _transientOperation;
private readonly IOperationScoped _scopedOperation;
private readonly IOperationSingleton _singletonOperation;
private readonly IOperationSingletonInstance _singletonInstanceOperation;
public OperationsController(OperationService operationService,
IOperationTransient transientOperation,
IOperationScoped scopedOperation,
IOperationSingleton singletonOperation,
IOperationSingletonInstance singletonInstanceOperation)
{
_operationService = operationService;
_transientOperation = transientOperation;
_scopedOperation = scopedOperation;
_singletonOperation = singletonOperation;
_singletonInstanceOperation = singletonInstanceOperation;
}
public IActionResult Index()
{
// viewbag contains controller-requested services
ViewBag.Transient = _transientOperation;
ViewBag.Scoped = _scopedOperation;
ViewBag.Singleton = _singletonOperation;
ViewBag.SingletonInstance = _singletonInstanceOperation;
// operation service has its own requested services
ViewBag.Service = _operationService;
return View();
}
}
}
Maintenant, deux requêtes distinctes sont faites à cette action du contrôleur:
Observez laquelle des valeurs OperationId
varie au sein d'une requête et entre les requêtes.
Les objets transitoires sont toujours différents; une nouvelle instance est fournie à chaque contrôleur et chaque service.
-
Les objets de portée sont les mêmes dans une requête, mais différents selon les différentes requêtes
Les objets Singleton sont les mêmes pour chaque objet et chaque requête (qu'une instance soit fournie ou non
ConfigureServices
)
Dans l'injection de dépendance de dotnet, il y a 3 durées de vie majeures:
Singleton {[4] } qui crée une seule instance dans l'application. Il crée l'instance pour la première fois et réutilise le même objet dans tous les appels.
Scoped les services lifetime sont créés une fois par requête dans la portée. Il est équivalent à Singleton dans la portée actuelle. par exemple. dans MVC il crée 1 instance par chaque requête http mais utilise la même instance dans les autres appels dans la même requête web.
Les services transitoires lifetime sont créés chaque fois qu'ils sont demandés. Cette durée de vie fonctionne le mieux pour les services légers et sans état.
Ici vous pouvez trouver et des exemples pour voir la différence :
Http://dotnetliberty.com/index.php/2015/10/15/asp-net-5-mvc6-dependency-injection-in-6-steps/
Https://codewala.net/2015/04/30/your-dependency-injection-ready-asp-net-asp-net-5/
Et ceci est le lien vers la documentation officielle :
Transient, scoped et singleton définissent le processus de création d'objet dans ASP.NET MVC core DI lorsque plusieurs objets du même type doivent être injectés. Dans le cas où vous êtes nouveau à L'injection de dépendance, vous pouvez voir cette DI IOC video
Vous pouvez voir le code du contrôleur ci-dessous dans lequel j'ai demandé deux instances de "IDal" dans le constructeur. Transient, Scoped et Singleton définissent si la même instance sera injectée dans "_dal" et "_dal1" ou différente.
public class CustomerController : Controller
{
IDal dal = null;
public CustomerController(IDal _dal
,IDal _dal1)
{
dal = _dal;
// DI of MVC core
// inversion of control
}
}
Transitoire :- En transitoire, de nouvelles instances d'objet seront injectées dans une seule requête et réponse. Voici une image instantanée où j'ai affiché des valeurs GUID.
Scoped: - dans scoped même instance d'objet sera injecté dans une seule requête et réponse.
Singleton: - dans Singleton, le même objet sera injecté dans toutes les requêtes et réponses. Dans ce cas, une instance globale de l'objet sera créée.
Ci-dessous est un simple diagramme qui explique visuellement le fondamental ci-dessus.
L'Image ci-dessus a été dessinée par L'équipe SBSS quand je prenais ASP.NET formation MVC à mumbai Formation, Un grand merci à L'équipe SBSS pour créer l'image ci-dessus.
- Singleton est une instance unique pour la durée de vie de l'application domaine.
- Scoped est une instance unique pour la durée de la scoped demande, ce qui signifie par HTTP demande dans ASP.NET.
- Transient est une instance unique par requêteCode .
Normalement, la demande de code doit être effectuée via un paramètre constructeur, comme dans
public MyConsumingClass(IDependency dependency)
Je voulais souligner dans la réponse de @ akazemis que les "services" dans le contexte de DI ne le font pas impliquent des services RESTful; les services sont des implémentations de dépendances qui fournissent des fonctionnalités.