gpt4 book ai didi

.net - 使用 Simple Injector 注册 NLog ILogger

转载 作者:行者123 更新时间:2023-12-04 00:56:02 25 4
gpt4 key购买 nike

有什么方法可以获取上下文,以便检索 loggerName并使用 LogManager.GetLogger(loggerName)而不是 LogManager.GetCurrentClassLogger() ?

我注意到 container.RegisterConditional()可以访问上下文。

另外,我想避免像 SimpleLogging.NLog 这样的解决方案目前。

最后,我愿意接受这不是正确的做法。顺便说一句,AOP 是我已经探索过的一个选项 (Is it a good practice to have logger as a singleton?)。

注意:我知道 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!");
}
}
}
}

最佳答案

您需要定义一个代理记录器,它将消息路由到正确的 Nlog 记录器。这个代理很简单:

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);
}
}

您可以将其注册为
container.RegisterConditional(typeof(ILogger), 
context => typeof(NLogProxy<>).MakeGenericType(context.Consumer.ImplementationType),
Lifestyle.Singleton, context => true);

您只需在任何需要记录的地方注入(inject) ILogger .

至于AOP。我不确定你的评论是什么意思

A wrapper that has to be maintained (NLog.ILogger contract is huge).



日志是 cross cutting concern并使用 decorator是应用横切关注点的好方法。使用装饰器,不可能记录每个(私有(private))函数调用入口和导出,但你为什么要这样呢?如您所见 here你可能不需要那个。在大多数情况下,调用服务(将数据传递给该服务)并使用完整的堆栈跟踪记录可能的异常这一简单事实将绰绰有余。

所以考虑一下:
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;
}
}
}

此装饰器将记录所有函数调用以及传递给服务的信息,还将记录任何异常。

但是这种方法会使类的数量增加 2,所以不是很 DRY .之所以会出现这个问题,是因为这种设计至少是次优的。使用围绕单个开放通用抽象的设计将完全解决这个问题。您可以阅读此设计 herehere .

在这种情况下,您将有一个“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);
}
}

这个单一的装饰器将记录你所有的命令。

这就是我对 AOP 的看法......

关于.net - 使用 Simple Injector 注册 NLog ILogger,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34643533/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com