requestdelegate net mvc injection framework dependency configureservices asp addscoped asp.net dependency-injection asp.net-core

mvc - ¿Por qué se usaría un contenedor DI de terceros sobre el contenedor DI de núcleo ASP.NET incorporado?



mvc dependency injection (4)

¿Cuál es la diferencia entre estos registros?

  • Transitorio: se instancia cada vez que se recupera
  • Alcance: instanciado una vez por solicitud http y estará disponible durante toda la vida de la solicitud http
  • Singleton: instanciado una vez y estará disponible durante toda la vida útil de su aplicación
  • Instancia: equivalente a singleton, excepto que proporciona la instancia del objeto en lugar del marco que crea la instancia

Fuente: http://www.khalidabuhakmeh.com/asp-vnext-dependency-injection-lifecycles , http://dotnetliberty.com/index.php/2015/10/15/asp-net-5-mvc6-dependency-injection-in-6-steps/

Como actualmente hay falta de documentación sobre el tema DI - Inyección de dependencia . ¿Cuáles son las ventajas y desventajas de utilizar la DI integrada sobre soluciones existentes como (Ninject, Autofac, StructureMap)? ¿Y cuáles son las limitaciones actuales de la inyección de dependencia predeterminada (si existe)?

Además, ¿alguien puede ayudarme a comprender cuál es la diferencia entre estos registros?

public void ConfigureServices(IServiceCollection services) { services.AddTransient<IService, Service>(); services.AddScoped<IService, Service>(); services.AddSingleton<IService, Service>(); services.AddInstance(service); }


Aquí se explica:

  • Transitorio: se crea una nueva instancia cada vez
  • Ámbito: se crea una única instancia dentro del ámbito actual. Es equivalente a Singleton en el alcance actual
  • Singleton: se crea una instancia única y actúa como un singleton
  • Instancia: se proporciona una instancia específica todo el tiempo. Usted es responsable de su creación inicial.

La versión alfa tenía estas limitaciones:

  • Solo admite inyección de constructor
  • Solo puede resolver tipos con un solo constructor público
  • No es compatible con funciones avanzadas (como el alcance del hilo o el descubrimiento automático)

Si no está escribiendo un producto DI predeterminado realmente complicado, el contenedor debería ser suficiente para usted. En otros casos, puede probar las bibliotecas que ya mencionó que tienen características avanzadas.

Mi consejo sería comenzar con el predeterminado y cambiar la implementación cuando (si) golpeas algo que no puedes hacer con él.


Para el desarrollo de productos de cualquier aplicación de tamaño razonable que practique un acoplamiento flojo y siga los principios SÓLIDOS, el contenedor DI de .NET Core no es adecuado porque:

  • No le ayuda a verificar su configuración, lo que hace que sea realmente difícil diagnosticar problemas que provienen de configuraciones incorrectas comunes. En una aplicación de tamaño razonable, en realidad es bastante difícil detectar estos errores usted mismo.
  • Es imposible aplicar inquietudes transversales utilizando interceptores o decorators de manera sostenible. Esto hace que el mantenimiento de cualquier aplicación de tamaño razonable sea realmente costoso.
  • Aunque admite la asignación de abstracciones genéricas abiertas a implementaciones genéricas abiertas, su implementación es bastante ingenua y no puede trabajar con tipos genéricos con restricciones de tipo, asignaciones de tipo genérico más complejas y varianza.
  • Es imposible realizar registros condicionales / contextuales, de tal manera que los registros solo se inyectan a un determinado conjunto de consumidores, mientras se utiliza el cableado automático. por ejemplo, cuando tiene dos componentes Service1 y Service2 que dependen de ILogger , es posible que desee inyectar Service1 con NullLogger y FileLogger con FileLogger , o que Service1 se inyecte con Logger<Service1> y Service2 con Logger<Service2> .

La razón principal para que existan esas limitaciones es porque el objetivo del contenedor integrado es proporcionar capacidades de DI especialmente al marco en sí, al tiempo que mantiene su conjunto de características al mínimo con la esperanza de que los contenedores de DI más maduros puedan integrarse con eso. En otras palabras, actúa como un mínimo común denominador (LCD). Debido a su función de LCD, nunca puede convertirse en un contenedor DI completamente equipado y práctico para el desarrollo de aplicaciones.

Si comienza con un proyecto nuevo y simple, mi consejo es aplicar Pure DI (que significa componentes cableados a mano dentro de la raíz de composición sin usar un contenedor) y resolver sus tipos conectando su IControllerActivator personalizado . Más adelante, cuando características como el registro automático y la intercepción mejoren la capacidad de mantenimiento de su raíz de composición, cambie a una de las bibliotecas DI establecidas que se ajuste a sus requisitos.


Para responder a su primera pregunta: parece que los documentos de ASP.NET se actualizaron y ahora indican claramente para qué es cada tipo de registro:

Los servicios ASP.NET se pueden configurar con las siguientes vidas:

Transitorio

Los servicios transitorios de por vida se crean cada vez que se solicitan. Esta vida útil funciona mejor para un servicio ligero y sin estado.

Alcance

Los servicios de por vida con ámbito se crean una vez por solicitud.

Semifallo

Los servicios de por vida de Singleton se crean la primera vez que se solicitan, y luego cada solicitud posterior utilizará la misma instancia. Si su aplicación requiere un comportamiento singleton, se recomienda permitir que el contenedor de servicios administre la vida útil del servicio en lugar de implementar el patrón de diseño singleton y administrar la vida útil de su objeto en la clase usted mismo.

Instancia [¡solo pre RTM!]

Puede elegir agregar una instancia directamente al contenedor de servicios. Si lo hace, esta instancia se utilizará para todas las solicitudes posteriores (esta técnica creará una instancia de ámbito Singleton). Una diferencia clave entre los servicios de instancia y los servicios Singleton es que el servicio de instancia se crea en ConfigureServices, mientras que el servicio Singleton se carga de forma diferida la primera vez que se solicita.

Actualizado en RTM

Tenga en cuenta que en Asp.Net Core RTM docs se eliminó la instancia. La instancia es básicamente lo mismo que Singleton, pero tenían una semántica de inicialización diferente (Singleton tenía una carga diferida). Pero ahora no hay una API AddInstance, solo AddSignleton que puede tomar una instancia ya creada.