我正在使用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)
答案 0 :(得分: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
拉出,就像在摘录中一样,您不必再传递参数了。
答案 1 :(得分: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);
}
}