net mvc multiple method inyeccion injection implementations dependency dependencias dependency-injection

dependency-injection - mvc - inyeccion de dependencias.net core



DI: ¿Cuánto inyectar? (3)

La regla general que uso a menudo es que me inyecto cosas que están en el camino de escribir correctamente las pruebas unitarias. Al hacer esto, a veces terminará abstrayendo las clases BCL (como DateTime.Now, File, etc.) y, a veces, sus propias cosas. Las cosas buenas para inyectar son servicios (como ICustomerService, ICustomerUnitOfWorkFactory o ICustomerRepository). No inyecte cosas como entidades, DTO y mensajes.

Sin embargo, hay otras razones para inyectar objetos, como poder reemplazar módulos en un momento posterior (por ejemplo, implementaciones de conmutación para validación, UI o O / RM), para permitir el desarrollo paralelo dentro o entre equipos y para reducir el mantenimiento. .

Prefiero usar la inyección de constructor y a menudo he observado que necesito que se inyecten aproximadamente 5 o más objetos en el constructor.

Como ya se notó, tener muchas dependencias podría ser causada por no adherirse al SRP . Sin embargo, lo que puede hacer es agrupar las dependencias comunes con la lógica en un servicio agregado e inyectarlas en los consumidores. También vea el artículo de Mark Seemann sobre servicios agregados .

Los objetos que son verdaderos singletons como la configuración de la aplicación o esas pequeñas clases de utilidad, ¿se inyectan?

Personalmente no soy un fan de la manera en que Ayende lo propone. Este es un contexto ambiental , que es un tipo específico de construcción de localizador de servicios . Hacer esto oculta la dependencia, porque las clases pueden llamar a esa clase estática sin que tenga que inyectarla. Si lo inyecta explícitamente, le queda mucho más claro que necesita un tiempo de prueba de unidad. Además de eso, hace que sea difícil escribir pruebas para marcos como MSTest que tienden a ejecutar pruebas en paralelo. Sin contramedidas, hace que sus pruebas sean poco confiables. Una mejor solución, para el ejemplo de DateTime.Now es tener una interfaz IClock , como se sugiere here . Como puede ver, la respuesta es mucho más alta que el enfoque de Ayende, que se muestra en la misma pregunta SO.

Los objetos comunes, como el registro, que se utilizan en casi todos los objetos, ¿deberían inyectarse?

Los inyecto en mi código, porque eso aclara las dependencias. Sin embargo, tenga en cuenta que en mi código casi nunca tengo que inyectar un registrador. Piense detenidamente en cada línea que desea registrar y no es realmente un fallo (o una preocupación transversal que debe colocarse en otro lugar). Por lo general, lanzo una excepción cuando sucedió algo que no esperaba. Me permite encontrar errores rápidamente. O para decirlo de otra manera: no filtre, pero falle rápidamente. Y, por favor, pregúntate: " ¿Registro demasiado? "

Espero que esto ayude.

Estoy escribiendo mi segunda aplicación de la vida real, que utiliza DI. En general creo que han dejado a un mejor diseño. Pero hay algunos olores de código, que no sé cómo resolver.

Prefiero usar la inyección de constructor y a menudo he observado que necesito que se inyecten aproximadamente 5 o más objetos en el constructor. Parece que son demasiados, tal vez sea un problema de diseño, no tener el SRP correcto. Pero creo que mi uso de DI también debe ser culpado.

Estoy buscando "mejores prácticas" o "regla general", en general parece que inyecto todo, que no está en el marco .Net, ¿es eso una exageración?

Para comenzar, aquí hay dos ejemplos de objetos que inyecto, pero no estoy seguro.

Los objetos que son verdaderos singletons como la configuración de la aplicación o esas pequeñas clases de utilidad, ¿se inyectan? Parece que se inyectan muy a menudo, la única razón para inyectarlos parece permitir cambiar el valor de las pruebas, pero Ayende parece haber resuelto el problema de otra manera: http://ayende.com/Blog/archive/2008/07/07/Dealing-with-time-in-tests.aspx .

Los objetos comunes, como el registro, que se utilizan en casi todos los objetos, ¿deberían inyectarse?


Mi regla personal es esta:

  • Inyectalo si quieres que sea inmutable.
  • Inyectarlo si desea poder sustituirlo con fines de prueba.

Cosas como los servicios pueden cumplir con ambos criterios: el consumidor nunca debe cambiarlo, y usted desea poder sustituirlo cuando llegue el momento de la prueba. Con los elementos inmutables, aún es posible que tengas una propiedad en el objeto consumidor, pero esa propiedad solo tendría un captador, no un establecedor. Si desea cambiar el valor, debe crear una nueva instancia del objeto.

¿Deberían inyectarse los madereros?

No hay razón para hacerlo. Los registradores normalmente se exponen a través de una clase estática y se actualizan a partir de las entradas de configuración, por lo que incluso para fines de prueba no es necesario inyectarlos.

¿Deberían inyectarse los singletones verdaderos como la configuración de la aplicación?

Una vez más, es un objeto accesible a nivel mundial que se puede modificar fácilmente para fines de prueba, por lo que no es necesario inyectarlo. La única vez que inyectaría esto es si el consumidor estuviera "desconectado"; Es decir, creado por reflexión o llamado como un servicio web u objeto remoto.

Si bien el DI es un buen patrón, muchas cosas buenas pueden ser insalubres. Si percibe un olor a código creciente, examine cada elemento que inyecta y hágase la siguiente pregunta: ¿ NECESITO inyectar este parámetro?


Un buen punto de partida es inyectar dependencias volátiles .

Es posible que también desee inyectar Dependencias estables para un mayor acoplamiento suelto, pero si necesita establecer prioridades, las Dependencias Volátiles es el mejor lugar para comenzar.

Con respecto a la sobreinyección del constructor , en realidad es solo un síntoma de romper el SRP: vea esta pregunta relacionada: ¿Cómo evitar la locura del constructor de inyección de dependencia?