13

解決する可能性のあるクラスに基づいてパラメーターで解決するコンポーネントを登録したいと考えています。(少しややこしいので、例を示します)。

ロガーを使用するオブジェクトは次のとおりです。

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

そのため、Logger を登録するときに、className を伝えられるようにしたいと考えています。これに似た方法があることを願っています:

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 が必要です。

前もって感謝します!

4

1 に答える 1

16

これが私がしていることです(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);
    }
}
于 2012-07-27T16:19:21.070 に答える