net microsoft injection extensions dependencyinjection dependency logging dependency-injection

logging - microsoft - .net core dependency injection



interfaces de inyección e inicio de sesión de dependencia (4)

Me preguntaba cuáles eran algunas de las mejores prácticas en torno a los marcos de registro y registro y la inyección de dependencias. Específicamente, si estoy diseñando una clase que necesita una forma de iniciar sesión, ¿cómo debo obtener una interfaz para iniciar sesión y mantener en mente la inyección de dependencia?

La inyección de dependencias parece indicar que las dependencias externas deben ser inyectadas desde el exterior (constructor o establecedores de propiedades), entonces ¿debería tomar una instancia ILog en el constructor y usarla en la clase? ¿Debo considerar registrar una dependencia opcional y obtenerla en un setter? ¿Estoy presionando para que haya demasiada flexibilidad al permitir que la interfaz de registro cambie y debería tomar una dependencia estricta de una interfaz de registro específica (por ejemplo, crear una variable de ILog estática mediante una llamada a un método de fábrica)? ¿Podría este método de fábrica llamar al contenedor para obtener la implementación ILog o creará conflictos de inicialización entre las variables estáticas que se están inicializando y el contenedor IoC que se está inicializando?

Debería estar haciendo esto:

public class MyService : ISomeService { private static readonly ILogger s_log = LoggingFactory.GetLogger(typeof(MyService)) ... }

o quizás esto:

public class MyService : ISomeService { protected virtual ILogger Logger {get; private set;} public MyService(ILogger logger, [other dependencies]) { Logger = logger; } }

o incluso esto:

public class MyService : ISomeService { public virtual ILogger Logger {get; set;} public MyService() { } }

Otros patrones o formas de hacer esto? ¿Qué están haciendo allí las personas? ¿Qué funciona y cuándo?


Esta no será una respuesta completa, pero una consideración será que si usted inyecta su ILog a través del constructor de su clase, entonces puede simular ese marco de registro para la prueba de su unidad. Otros pensamientos ... Un setter de propiedades para pasar en ILog significa que no puede registrar acciones desde el constructor. Además, no está seguro de si su instancia tiene un ILog disponible, lo que significa que tiene que ajustar cada llamada con una prueba para una instancia de ILog válida.


Me limitaría a inyectarlo y usar una interfaz. Principalmente para facilitar las pruebas. Hacerlo es más fácil de sustituir un simulacro o un talón cuando se prueba el objeto consumidor.

Me basaría si usé la inyección de constructor o setter sobre la importancia del registro para la clase consumidora. Si quieres que sea crítico, entonces yo preferiría la inyección del constructor, si es opcional, entonces setter.

No veo dónde el uso de un método de fábrica no podría funcionar con el contenedor, sin embargo, luego hace que probar la clase de consumidor dependa de una configuración adecuada de este método de fábrica.


¿Mi consejo? Envuelva las interfaces de registro en la suya. Tomé una dependencia de Log4Net una vez, me quemé y tuve que refacturar muchos de mis proyectos debido a eso.


Es genial que estés investigando la inversión de control y la inyección de dependencia.

Pero para su pregunta, hay otro concepto que podría interesarle: programación orientada a aspectos.

En .NET, hay algunos buenos marcos disponibles para hacer una programación orientada a aspectos, incluyendo Castle, LinFu y el Bloque de aplicaciones de inyección de políticas de Microsoft. De hecho, algunos contenedores de inversión de control también tienen algunas características orientadas a aspectos.

Estos conceptos y herramientas ayudan a hacer que preocupaciones tales como el registro tomen un asiento de fondo en términos de ruido de código, y que se manejen automágicamente.