2012-07-27 13 views
10

Sto cercando di registrare un componente da risolvere con parametri basati sulla classe per cui potrebbe essere risolto. (Suona un po 'di confusione, quindi mostrerò un esempio).Autofac: registra componente e risolve a seconda della risoluzione genitore

Ecco un oggetto che utilizza un registratore:

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

Ora il logger che viene passato in potrebbe essere diverso da classe a classe. Così ho un'idea piuttosto patch per come fare qui di seguito:

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; 
    } 
} 

Così, quando mi registro Logger Voglio essere in grado di dire che il className. Spero ci sia un modo per farlo simile a questo:

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" 

Il motivo che voglio fare in questo modo è quello di evitare la registrazione di ogni classe a implementare con un registratore con autofac nel codice. Voglio essere in grado di registrare tutti gli oggetti in xml e semplicemente avere un LoggerModule, che aggiunge questa registrazione.

Grazie in anticipo!

risposta

14

Ecco quello che faccio (ILOG è solo la mia wrapper per 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

sto cercando di implementare il modulo, ma io non sto trovando la builder.Register() la funzione non generico . – philt5252

+0

È un metodo di estensione che esiste nella classe 'Autofac.RegistrationExtensions'. Dovresti assolutamente averlo. –

+0

haha ​​... non importa ... Non ho finito di digitare il codice e ho dimenticato che C# implica il tipo da Func. – philt5252

Problemi correlati