2009-02-06 4 views
26

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 conseguir una interfaz para iniciar sesión y mantener en mente la inyección de dependencia?interfaces de inyección e inicio de sesió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 de 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 hacer esto:

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

o tal vez 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?

+0

Optaría por la segunda o tercera opción dependiendo de si tener o no un registrador para el servicio se considera crítico. – toad

Respuesta

4

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

Pero para su pregunta, hay otro concepto en el que debería considerar: la 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.

+1

El registro es el "hola, mundo" de la programación orientada a aspectos. Definitivamente es una preocupación transversal. – duffymo

+6

El rastreo y las excepciones del método de manejo es una cosa, pero ¿qué ocurre con el registro de eventos positivos? ¿Qué pasa con las condiciones de advertencia que necesita para iniciar sesión cuando suceden, pero no interrumpe el flujo de programa real. ¿Puedes cubrir "todos los casos (relevantes)" con aspectos? – Cornelius

2

Esto 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 se sabe con certeza si su instancia tiene un ILog disponible, lo que significa que debe envolver cada llamada con una prueba para una instancia de ILog válida.

+0

+1 para obtener sugerencias sobre pruebas unitarias + simulacros de objetos. –

0

Me gustarí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 gustaría basarme si utilicé la inyección del constructor o del colocador en 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.

4

¿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.

+0

http://stackoverflow.com/questions/940831/how-to-use-log4net-with-dependency-injection – Karsten

+0

@Karsten incluso si se inyecta el registrador, debe agregar una referencia a cada proyecto que lo usará para que la clase o la interfaz se puede resolver. La solución de usar una devolución de llamada aísla el 100% de la implementación del alcance donde se crea la clase. – QueueHammer

Cuestiones relacionadas