2012-07-27 9 views
10

Chcę zarejestrować komponent do rozwiązania za pomocą parametrów opartych na klasie, dla której może on być rozwiązywany. (To trochę dezorientuje, więc pokażę przykład).Autofac: Zarejestruj komponent i rozwiąż problem w zależności od rozpoznawania rodzica

Oto przedmiot, który korzysta z rejestratora:

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

Teraz rejestrator, który jest przekazywany w może różnić się od klasy do klasy. Więc mam raczej poprawionej pomysł jak to zrobić poniżej:

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

Więc kiedy zarejestrować Logger Chcę móc powiedzieć go className. Mam nadzieję, że istnieje sposób, aby zrobić to podobne do tego:

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" 

Powód chcę zrobić to w ten sposób jest uniknąć rejestracji każdej klasy zaimplementować z rejestratorem z autofac w kodzie. Chcę być w stanie zarejestrować wszystkie obiekty w xml i po prostu mieć LoggerModule, który dodaje tę rejestrację.

Z góry dziękuję!

Odpowiedz

14

Oto co mam zrobić (Ilog to tylko moje własne otoki wokół 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

Ja próbuje wdrożyć moduł, ale nie jestem znalezienie builder.Register() funkcji nierodzajową . – philt5252

+0

Jest to metoda rozszerzenia, która istnieje w klasie 'Autofac.RegistrationExtensions'. Powinieneś zdecydowanie to mieć. –

+0

haha ​​... nevermind ... Nie skończyłem pisania kodu i zapomniałem, że C# będzie implikować typ z Func. – philt5252

Powiązane problemy