one*_*ill 2 c# log4net simple-injector
为了尝试使用 Log4net 获得良好的日志记录抽象,我从这篇 SO 帖子中获取了抽象,并从这篇 SO 帖子中获取了适配器,并尝试让它们一起工作。
真正剩下要做的就是配置容器,而这是我尚未成功完成的部分。
我尝试过的配置是
public static class InfrastructureRegistry
{
public static void RegisterLoggingServices(this Container container)
{
container.RegisterConditional(typeof(ILog), c => LogManager.GetLogger(
c.Consumer.ImplementationType).GetType(),
Lifestyle.Scoped, c => true);
container.RegisterPerWebRequest<ILogger, Log4netAdapter>();
}
}
Run Code Online (Sandbox Code Playgroud)
正如您从代码中看到的,我想要一个特定的 log4net 记录器,它从注入的类中获取其类型。虽然大多数日志记录都是以包罗万象的方式完成的,但我希望在较低层中进行一些日志记录,例如当表单验证失败时。
我ActivationException通过该配置得到的是:
LogImpl 类型的构造函数包含名称为“logger”且类型为 ILogger 的未注册参数。请确保ILogger已注册,或更改LogImpl的构造函数。
不太确定从这里去哪里,所以任何帮助将不胜感激。
编辑
抱歉,我应该指出,我正在尝试编写它,这样我只需编写此配置一次。以下工厂函数有效,但我不想每次要注入记录器时都手动添加更多配置:
container.RegisterPerWebRequest<ILog>(() => LogManager.GetLogger(typeof(LoginController)));
Run Code Online (Sandbox Code Playgroud)
您指向的示例适配器假定应用程序中的每个组件都有一个记录器,而您希望有一个“了解”其使用者的特定记录器,以便它可以将日志消息与原始类相关联。
尽管在使用 log4net 和 NLog 等工具时这似乎是一种非常常见的做法,但根据我的经验,这一要求通常来自于代码中的太多地方进行日志记录这一事实。请阅读此 stackoverflow q/a以获取更多信息。
也就是说,如果您想有条件地注册记录器,则必须将适配器更改为通用类;这样你就可以使注册成为有条件的:
public class Log4netAdapter<T> : ILogger
{
private static readonly log4net.ILog logger = LogManager.GetLogger(typeof(T));
public void Log(LogEntry entry)
{
if(entry.LoggingEventType == LoggingEventType.Information)
logger.Info(entry.Message, entry.Exception);
else if(entry.LoggingEventType == LoggingEventType.Warning)
logger.Warn(entry.Message, entry.Exception);
else if(entry.LoggingEventType == LoggingEventType.Error)
logger.Error(entry.Message, entry.Exception);
else
logger.Fatal(entry.Message, entry.Exception);
}
}
Run Code Online (Sandbox Code Playgroud)
使用这个通用类,您可以执行以下条件/上下文注册:
container.RegisterConditional(
typeof(ILogger),
c => typeof(Log4netAdapter<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
Run Code Online (Sandbox Code Playgroud)