2009-07-21 19 views
9

Me gustaría inyectar ILog en mis clases, no en ILoggerFactoryAdapter, pero el ILoggerFactoryAdapter necesita el nombre de la clase que llama (la clase que quiere registrar algo, para poder categorizarlo correctamente), así puede Autofac identificar de alguna manera la clase que están solicitando el ILog y crean automáticamente el ILog de fábrica?Fábrica automática con Common.Logging y Autofac?

Respuesta

9

Bailey Ling se acercó con un gran acercamiento que no utiliza la pila caminar - ver post aquí: http://groups.google.com/group/autofac/msg/704f926779cbe8b3

+0

La solución de Bailey es excelente, pero no funciona con la integración de WebForms. Las páginas y los controles de usuario no están registrados, por lo que el controlador de eventos nunca se dispara. Hay un comentario en el wiki del sitio del proyecto Autofac con el mismo efecto (http://code.google.com/p/autofac/wiki/Log4NetIntegration). –

+1

El código está un poco desactualizado, pero afortunadamente Autofac lo adaptó a un ejemplo formal: http://docs.autofac.org/en/latest/examples/log4net.html – Mugen

5

He intentado hacer esto también, pero no pude encontrar una manera de obtener acceso a la pila de activación de autofac (sin parches) para obtener el tipo que se va a inyectar con la instancia del registrador.

a continuación es el "Obras en mi máquina" forma certificada (Autofac-1.4.3.536)

protected override void Load(ContainerBuilder builder) 
     { 
      const string loggerName = "Logger.Name"; 

      builder. 
       Register((c, p) => LogManager.GetLogger(p.Named<string>(loggerName))). 
       OnPreparing((c, p) => 
      { 
       var stack = p.Context.GetActivationStack(); 
       var requestingType = "default"; 
       if (stack != null && stack.Length > 1) requestingType = stack[1].Description; 
       var parameters = new List<Parameter>(p.Parameters) { new NamedParameter(loggerName, requestingType) }; 
       p.Parameters = parameters; 

      }). 
      FactoryScoped(); 
} 

static class ContextExtensions 
{ 
    public static Autofac.Service[] GetActivationStack(this Autofac.IContext context) 
    { 
     const string notSupportedMessage = "GetActivationStack not supported for this context."; 

     var type = context.GetType(); 
     if (type.FullName != "Autofac.Context") throw new NotSupportedException(notSupportedMessage); 

     var field = type.GetField("_componentResolutionStack", BindingFlags.Instance | BindingFlags.NonPublic); 
     if (field == null) throw new NotSupportedException(notSupportedMessage); 

     var activationStack = field.GetValue(context) as Stack<Autofac.Service>; 
     if (activationStack == null) throw new NotSupportedException(notSupportedMessage); 

     return activationStack.ToArray(); 
    } 
} 
+0

¡wow, gracias, lo probaré inmediatamente! –

+0

funciona como el encanto! ¡Gracias! –

Cuestiones relacionadas