2012-07-27 18 views
10

解決する可能性のあるクラスに基づいてパラメータで解決するコンポーネントを登録したいと考えています。 (それはちょっと混乱しているように聞こえるので、例を示します)。クラスへのクラスとは異なる可能性があり、渡されたAutofac:コンポーネントを登録し、解決する親に応じて解決

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

今ロガー:

はここでロガーを使用するオブジェクトです。だから私は、以下のことを行う方法についてではなくパッチを当てたアイデアを持っている:私はロガーを登録するときだから私はそれをクラス名を伝えることができるようにしたい

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

。私はそれを次のような操作を行うための方法があります願っています:

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" 

私はこのようにそれをしたい理由は、私はコード内のautofacとロガーを実装する各クラスの登録を避けるためです。私は、すべてのオブジェクトをxmlに登録でき、この登録を追加するLoggerModuleを用意したいと考えています。

ありがとうございます!ここで

答えて

14

は(のILogは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

私はあなたのモジュールを実装しようとするんだけど、私はbuilder.Register()非ジェネリック機能を見つけることありませんよ。 – philt5252

+0

これは 'Autofac.RegistrationExtensions'クラスに存在する拡張メソッドです。あなたは間違いなくそれを持っているはずです。 –

+0

haha​​ ... nevermind ...私はコードの入力を終了していないし、C#がFuncからタイプを暗示することを忘れてしまった。 – philt5252

関連する問題