1

我正在使用 autofac 并尝试注册 WebApi 控制器。每个控制器都采用一个唯一的Logging.ILog作为构造函数参数(这是我的 ILog 适应 log4net ILog)。当记录器被解析时,我希望根据它们被解析的控制器来命名它们。

像这样的东西:

builder.Register(c => log4net.LogManager.GetLogger("NEED CONTROLLER NAME HERE"));   
builder.Register(c => new Logging.Adapters.Log4NetAdapter(c.Resolve<log4net.ILog>()));
builder.RegisterType<Logging.Adapters.Log4NetAdapter>().As<Logging.ILog>();         
builder.RegisterApiControllers(System.Reflection.Assembly.GetExecutingAssembly());

知道如何让每个 WebApi 控制器根据控制器类型名称接收单独的记录器名称吗?

以下似乎可行,但似乎并不理想。

builder.Register(c => log4net.LogManager.GetLogger(c.ComponentRegistry.Registrations.Last().Activator.LimitType.Name));
builder.Register(c => new Logging.Adapters.Log4NetAdapter(c.Resolve<log4net.ILog>()));
builder.RegisterType<Logging.Adapters.Log4NetAdapter>().As<Logging.ILog>();       
builder.RegisterApiControllers(System.Reflection.Assembly.GetExecutingAssembly());

我是autofac的新手,所以请耐心等待。
如果您注意到上面我有一个附加层或我自己的 ILog 和 Log4NetAdapter/Wrapper,那么控制器和实际的 log4net 之间有几层注册。

我需要类似的东西:

APIController <- Logging.ILog <- Logging.Adapters.Log4NetAdapter <- log4net.ILog <- log4net.LogManager.GetLogger(APIController-Name)
4

2 回答 2

0

我使用带有包装器的 NLog,但它当然可以转换为 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.ResolveLog(forType));

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

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

public static class ResolveLogExtension
{
    public static ILog ResolveLog<TService>(this IComponentContext context)
    {
        return context.ResolveLog(typeof (TService));
    }

    public static ILog ResolveLog(this IComponentContext context, Type type)
    {
        return context.Resolve<ILog>(TypedParameter.From(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 NLogLogger : ILog
{
    private readonly Logger _log;

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

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

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

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

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

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

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

    public void Fatal(Exception ex, string format, params object[] args)
    {
        _log.FatalException(string.Format(format, args), ex);
    }
}
于 2012-09-26T14:35:50.700 回答
0

Autofac wiki上提供了 Log4net 集成文档。

从文档:

public class LogInjectionModule : Module
{
    protected override void AttachToComponentRegistration(IComponentRegistry registry, IComponentRegistration registration)
    {
        registration.Preparing += OnComponentPreparing;
    }

    static void OnComponentPreparing(object sender, PreparingEventArgs e)
    {
        var t = e.Component.Activator.LimitType;
        e.Parameters = e.Parameters.Union(new[]
        {
            new ResolvedParameter((p, i) => p.ParameterType == typeof(ILog), (p, i) => LogManager.GetLogger(t))
        });
    }
}

稍微修改上面的内容以将名称从LimitType.

于 2012-09-25T20:42:03.267 回答