services net mvc iservicecollection inyeccion injection dependency dependencias configureservices asp addscoped c# asp.net-core-mvc

c# - net - iservicecollection



¿Cuál es la diferencia entre los métodos services.AddTransient, service.AddScoped y service.AddSingleton en ASP.NET Core? (4)

Quiero implementar la inyección de dependencias en Asp.Net Core . Entonces, después de agregar estos códigos al método ConfigureServices , ambas formas funcionan.

¿Cuál es la diferencia entre services.AddTransient y service.AddScope es Asp.Net Core?

public void ConfigureServices(IServiceCollection services) { // Add framework services. // Add application services. services.AddTransient<IEmailSender, AuthMessageSender>(); services.AddScoped<IEmailSender, AuthMessageSender>(); }


En la inyección de dependencia de dotnet hay 3 vidas principales:

Singleton que crea una sola instancia a lo largo de la aplicación. Crea la instancia por primera vez y reutiliza el mismo objeto en todas las llamadas.

Los servicios de por vida con alcance se crean una vez por solicitud dentro del alcance. Es equivalente a Singleton en el alcance actual. p.ej. en MVC crea 1 instancia por cada solicitud http, pero usa la misma instancia en las otras llamadas dentro de la misma solicitud web.

Los servicios transitorios de por vida se crean cada vez que se solicitan. Esta vida funciona mejor para servicios livianos y sin estado.

Aquí puedes encontrar y ejemplos para ver la diferencia:

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/

Y este es el enlace a la documentación oficial:

docs


Transitorio, con ámbito y singleton definen el proceso de creación de objetos en ASP.NET MVC core DI cuando se deben inyectar múltiples objetos del mismo tipo. En caso de que sea nuevo en la inyección de dependencia, puede ver este video DI IOC

Puede ver el siguiente código del controlador en el que he solicitado dos instancias de "IDal" en el constructor. Transient, Scoped y Singleton definen si la misma instancia se inyectará en "_dal" y "_dal1" o diferente.

public class CustomerController : Controller { IDal dal = null; public CustomerController(IDal _dal ,IDal _dal1) { dal = _dal; // DI of MVC core // inversion of control } }

Transitorio: - En las instancias de objetos nuevos transitorios se inyectarán en una sola solicitud y respuesta. A continuación se muestra una imagen de la instantánea donde se muestran los valores de GUID.

Con ámbito: - En el mismo ámbito, la instancia de objeto se inyectará en una sola solicitud y respuesta.

Singleton: - En Singleton, el mismo objeto se inyectará en todas las solicitudes y respuestas. En este caso se creará una instancia global del objeto.

A continuación se muestra un diagrama simple que explica visualmente lo fundamental anterior.

La imagen de arriba fue dibujada por el equipo de SBSS cuando estaba tomando el entrenamiento de ASP.NET MVC en el entrenamiento de Mumbai , un gran agradecimiento al equipo de SBSS por crear la imagen de arriba.


TL; DR

Los objetos transitorios son siempre diferentes; Se proporciona una nueva instancia a cada controlador y cada servicio.

Los objetos con alcance son los mismos dentro de una solicitud, pero diferentes en diferentes solicitudes.

Los objetos singleton son los mismos para cada objeto y cada solicitud.

Para más aclaraciones, este ejemplo de docs muestra la diferencia:

Para demostrar la diferencia entre estas opciones de vida útil y de registro, considere una interfaz simple que represente una o más tareas como una operación con un identificador único, OperationId . Dependiendo de cómo configuremos la vida útil de este servicio, el contenedor proporcionará las mismas o diferentes instancias del servicio a la clase solicitante. Para que quede claro qué tiempo de vida se solicita, crearemos un tipo de opción de por vida:

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 { } }

Implementamos estas interfaces utilizando una sola clase, Operation , que acepta un Guid en su constructor, o usa un nuevo Guid si no se proporciona ninguno.

A continuación, en ConfigureServices , cada tipo se agrega al contenedor de acuerdo con su vida útil nombrada:

services.AddTransient<IOperationTransient, Operation>(); services.AddScoped<IOperationScoped, Operation>(); services.AddSingleton<IOperationSingleton, Operation>(); services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty)); services.AddTransient<OperationService, OperationService>();

Tenga en cuenta que el servicio IOperationSingletonInstance está utilizando una instancia específica con un ID conocido de Guid.Empty por lo que estará claro cuando este tipo esté en uso. También hemos registrado un OperationService que depende de cada uno de los otros tipos de Operation , para que quede claro en una solicitud si este servicio está obteniendo la misma instancia que el controlador, o una nueva, para cada tipo de operación. Todo lo que hace este servicio es exponer sus dependencias como propiedades, por lo que se pueden mostrar en la vista.

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; } } }

Para demostrar el tiempo de vida del objeto dentro y entre solicitudes individuales separadas a la aplicación, la muestra incluye un IOperation de OperationsController que solicita cada tipo de tipo de IOperation así como un Servicio de OperationService . La acción de Index luego muestra todos los valores de OperationId del controlador y del servicio.

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(); } } }

Ahora se hacen dos solicitudes separadas a esta acción del controlador:

Observe cuál de los valores de OperationId varía dentro de una solicitud y entre solicitudes.

  • Los objetos transitorios son siempre diferentes; Se proporciona una nueva instancia a cada controlador y cada servicio.

  • Los objetos con alcance son los mismos dentro de una solicitud, pero diferentes en diferentes solicitudes

  • Los objetos Singleton son los mismos para cada objeto y cada solicitud (independientemente de si se proporciona una instancia en ConfigureServices )


  • Singleton es una instancia única para la vida útil del dominio de la aplicación.
  • Scoped es una instancia única durante la duración de la solicitud con alcance, lo que significa que por solicitud HTTP en ASP.NET.
  • Transitorio es una instancia única por solicitud de código .

Normalmente, la solicitud de código se debe realizar a través de un parámetro constructor, como en

public MyConsumingClass(IDependency dependency)

Quería señalar en la respuesta de @ akazemis que "servicios" en el contexto de DI no implica servicios RESTful; Los servicios son implementaciones de dependencias que proporcionan funcionalidad.