Gon*_*nto 12 .net dependency-injection nlog ioc-container simple-injector
有什么方法可以获得上下文所以我可以检索loggerName并使用LogManager.GetLogger(loggerName)而不是LogManager.GetCurrentClassLogger()?
我注意到container.RegisterConditional()可以访问上下文.
另外,我现在想避免像SimpleLogging.NLog这样的解决方案.
最后,我愿意接受这不是正确的方法.顺便说一下,AOP是我已经探索过的一个选项(将记录器作为单身人员是一种很好的做法吗?).
注意:我知道GetCurrentClassLogger()获取与.NET反射检索的相同信息.
using NLog;
using SimpleInjector;
namespace DependencyInjection
{
class Program
{
private static Container _container;
static void Main(string[] args)
{
Bootstrap();
_container.GetInstance<Greeter>().Greet();
}
private static void Bootstrap()
{
_container = new Container();
_container.Register<ILogger>(() => LogManager.GetCurrentClassLogger(), Lifestyle.Transient);
_container.Register<Greeter>();
_container.Verify();
}
public class Greeter
{
private ILogger _logger;
public Greeter(ILogger logger)
{
_logger = logger;
}
public void Greet()
{
_logger.Log(LogLevel.Info, "Hello world!");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Ric*_*Net 14
您需要定义一个代理记录器,它将消息路由到正确的Nlog Logger.这个代理非常简单:
public class NLogProxy<T> : ILogger
{
private static readonly NLog.ILogger logger =
LogManager.GetLogger(typeof (T).FullName);
void ILogger.Log(string message)
{
logger.Log(LogLevel.Info, message);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以将此注册为
container.RegisterConditional(typeof(ILogger),
context => typeof(NLogProxy<>).MakeGenericType(context.Consumer.ImplementationType),
Lifestyle.Singleton, context => true);
Run Code Online (Sandbox Code Playgroud)
你需要记录的任何地方你都必须注射ILogger.
至于AOP.我不确定你的评论是什么意思
必须维护的包装器(NLog.ILogger合同很大).
记录是一个跨领域的问题,使用装饰器是应用横切问题的好方法.使用装饰器,无法记录每个(私有)函数调用入口和出口,但为什么要这样?你可以在这里阅读,你可能不需要那样做.在大多数情况下,使用完整的堆栈跟踪记录服务被调用(传递给此服务的数据)和可能的异常的简单事实将是绰绰有余的.
所以考虑一下:
public interface ISomeService
{
void DoSomething(string someParameter);
}
public class SomeServiceDecorator : ISomeService
{
private readonly ISomeService decoratee;
private readonly ILogger logger;
public SomeServiceDecorator(ISomeService decoratee, ILogger logger)
{
this.decoratee = decoratee;
this.logger = logger;
}
public void DoSomething(string someParameter)
{
try
{
this.logger.Log(string.Format("Do something called with {0}", someParameter));
this.decoratee.DoSomething(someParameter);
}
catch (Exception e)
{
this.logger.Log(e.ToString());
throw;
}
}
}
Run Code Online (Sandbox Code Playgroud)
此装饰器将使用传递给服务的信息记录所有函数调用,并且还将记录任何异常.
但是这种方法会使类的数量增加2,所以不是很干.引起此问题是因为此设计至少是次优的.围绕单个开放式通用抽象使用设计将完全解决此问题.你可以在这里和这里阅读这个设计.
在这种情况下,你将有一个`LoggingDecorator'
public class LoggingCommandHandlerDecorator<T> : ICommandHandler<T>
{
private readonly ICommandHandler<T> decoratee;
private readonly ILogger logger;
public LoggingCommandHandlerDecorator(ICommandHandler<T> decoratee, ILogger logger)
{
this.decoratee = decoratee;
this.logger = logger;
}
public void Handle(T command)
{
// serialize command to json and log
this.logger.Log(serializedcommandData);
this.decoratee.Handle(command);
}
}
Run Code Online (Sandbox Code Playgroud)
而这个装饰器将记录您的所有命令.
那是我对AOP的看法....
| 归档时间: |
|
| 查看次数: |
5882 次 |
| 最近记录: |