我使用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 /包装,以便有控制器和实际之间log4net的注册几个层。
我需要这样的东西:
APIController <- Logging.ILog <- Logging.Adapters.Log4NetAdapter <- log4net.ILog <- log4net.LogManager.GetLogger(APIController-Name)
log4net的集成文档都可以在Autofac维基 。
从文档:
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
,在你的摘录,你不会有任何更多的传递参数。
我用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);
}
}
文章来源: When using autofac, how do I use a WebAPI controller type name as a parameter to a depencency's Register?