Quiero implementar la dependency injection 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 los servicios. Los métodos AddTransient y service.AddScope son Asp.Net Core?
public void ConfigureServices(IServiceCollection services) { // Add framework services. // Add application services. services.AddTransient(); services.AddScoped(); }
Para mayor aclaración, este ejemplo de asp.net docs muestra la diferencia:
Para demostrar la diferencia entre estas opciones de vida 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 duración de este servicio, el contenedor proporcionará las mismas o diferentes instancias del servicio para la clase solicitante. Para aclarar qué tiempo de vida se está solicitando, 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 usando una sola clase, Operation
, que acepta un Guid
en su constructor, o utiliza un nuevo Guid
si no se proporciona.
A continuación, en ConfigureServices
, cada tipo se agrega al contenedor de acuerdo con su duración definida:
services.AddTransient(); services.AddScoped(); services.AddSingleton(); services.AddSingleton(new Operation(Guid.Empty)); services.AddTransient();
Tenga en cuenta que el servicio IOperationSingletonInstance
está utilizando una instancia específica con un ID conocido de Guid.Empty
por lo que quedará claro cuando este tipo esté en uso. También registramos un OperationService
que depende de cada uno de los otros tipos de Operation
, de modo que quede claro en una solicitud si este servicio obtiene 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 la vida útil del objeto dentro y entre solicitudes individuales separadas a la aplicación, la muestra incluye un OperationsController
que solicita cada tipo de tipo IOperation
así como también un OperationService
. La acción Index
muestra todos los valores 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 realizan dos solicitudes por separado a esta acción del controlador:
Observe cuál de los valores de OperationId
varía dentro de una solicitud, y entre las solicitudes.
Los objetos transitorios son siempre diferentes; se proporciona una nueva instancia a cada controlador y cada servicio.
Los objetos delimitados 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
)
En la dependency injection de dotnet hay 3 vidas principales:
Singleton que crea una sola instancia en toda la aplicación. Crea la instancia por primera vez y reutiliza el mismo objeto en todas las llamadas.
Los servicios con scope de por vida se crean una vez por solicitud dentro del scope. Es equivalente a Singleton en el scope 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 de duración transitoria se crean cada vez que se solicitan. Esta vida útil funciona mejor para servicios livianos y apátridas.
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:
Normalmente, la solicitud del código debe hacerse 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.
Transient, Scoped 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 del DI IOC
Puede ver el código del controlador a continuación 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 instancias transitorias de objetos nuevos, se inyectará en una única solicitud y respuesta. A continuación se muestra una imagen instantánea donde se muestran los valores GUID.
Alcance: – En el mismo objeto, la instancia del 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 diagtwig simple que explica los aspectos fundamentales anteriores visualmente.
La imagen de arriba fue dibujada por el equipo de SBSS cuando estaba tomando capacitación ASP.NET MVC en entrenamiento de Mumbai , muchas gracias al equipo de SBSS para crear la imagen de arriba.