2012-07-27 10 views
10

Estoy queriendo registrar un componente para resolver con parámetros basados ​​en la clase que podría estar resolviendo. (Eso suena un poco confuso, entonces mostraré un ejemplo).Autofac: componente de registro y resolución según resolver padre

Aquí es un objeto que utiliza un registrador:

class MyObject : IMyObject 
{ 
    public ILogger Logger; 
    public MyObject(ILogger logger) 
    { 
     Logger = logger; 
    } 
} 

Ahora el registrador que se pasa podría ser diferente de una clase a otra. Así que tengo una idea bastante parcheado de cómo hacerlo a continuación:

class MyLogger : ILogger 
{ 
    public string Name{get; protected set;} 

    public static ILogger GetLogger(string className) 
    { 
     Name = className; 
     MyLogger logger; 
     // Do something to choose a logger for that specific class 
     return logger; 
    } 
} 

Así que cuando me registro Logger Quiero ser capaz de decir que el className. Estoy esperando que hay una manera de hacerlo similar a esto:

ContainerBuilder builder = new ContainerBuilder(); 

builder.Register<MyLogger>(ctx => 
    { 
     string className = //Get resolving class name somehow; 
     return MyLogger.GetLogger(className); 
    }).As<ILogger>(); 

builder.Register<MyObject>().As<IMyObject>(); 

var container = builder.Build(); 

IMyObject myObj = container.Resolve<IMyObject>(); 

//myObject.Logger.Name should now == "MyObject" 

La razón por la que quiero hacerlo de esta manera es evitar el registro de cada clase implemento con un registrador con autofac en el código. Quiero poder registrar todos los objetos en xml, y simplemente tener un LoggerModule, que agrega este registro.

¡Gracias de antemano!

Respuesta

14

Aquí es lo que hago (ILOG es sólo mi propia envoltura alrededor de log4net):

public class LoggingModule : Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.Register((c, p) => GetLogger(p.TypedAs<Type>())); 
    } 

    protected override void AttachToComponentRegistration(
     IComponentRegistry registry, IComponentRegistration registration) 
    { 
     registration.Preparing += 
      (sender, args) => 
      { 
       var forType = args.Component.Activator.LimitType; 

       var logParameter = new ResolvedParameter(
        (p, c) => p.ParameterType == typeof (ILog), 
        (p, c) => c.Resolve<ILog>(TypedParameter.From(forType))); 

       args.Parameters = args.Parameters.Union(new[] {logParameter}); 
      }; 
    } 

    public static ILog GetLogger(Type type) 
    { 
     return new Log4NetLogger(type); 
    } 
} 

public interface ILog 
{ 
    void Debug(string format, params object[] args); 
    void Info(string format, params object[] args); 
    void Warn(string format, params object[] args); 

    void Error(string format, params object[] args); 
    void Error(Exception ex); 
    void Error(Exception ex, string format, params object[] args); 

    void Fatal(Exception ex, string format, params object[] args); 
} 

public class Log4NetLogger : ILog 
{ 
    private readonly log4net.ILog _log; 

    static Log4NetLogger() 
    { 
     XmlConfigurator.Configure(); 
    } 

    public Log4NetLogger(Type type) 
    { 
     _log = LogManager.GetLogger(type); 
    } 

    public void Debug(string format, params object[] args) 
    { 
     _log.DebugFormat(format, args); 
    } 

    public void Info(string format, params object[] args) 
    { 
     _log.InfoFormat(format, args); 
    } 

    public void Warn(string format, params object[] args) 
    { 
     _log.WarnFormat(format, args); 
    } 

    public void Error(string format, params object[] args) 
    { 
     _log.ErrorFormat(format, args); 
    } 

    public void Error(Exception ex) 
    { 
     _log.Error("", ex); 
    } 

    public void Error(Exception ex, string format, params object[] args) 
    { 
     _log.Error(string.Format(format, args), ex); 
    } 

    public void Fatal(Exception ex, string format, params object[] args) 
    { 
     _log.Fatal(string.Format(format, args), ex); 
    } 
} 
+0

Estoy tratando de poner en práctica su módulo, pero no estoy encontrando la builder.Register() la función no genérico . – philt5252

+0

Es un método de extensión que existe en la clase 'Autofac.RegistrationExtensions'. Definitivamente deberías tenerlo. –

+0

jaja ... no importa ... No terminé de escribir el código, y olvidé que C# implicará el tipo de Func. – philt5252

Cuestiones relacionadas