通过 DispatchProxy 进行 C# 日志记录

C# Logging via DispatchProxy

考虑到许多可能的方法来处理像日志记录这样的横切关注点,我认为处理它们的一个好方法是通过拦截。 (Mark Seemann 在他的书中 "Dependency Injection in .NET" 也提到拦截是横切依赖项的有效解决方案。)

但在我的具体情况下,我想使用 .Net Core,它是 DispatchProxy. And for Logging Microsoft's Logging Extension

使用通用代理拦截方法调用并在 Debug level 上记录调用非常容易。但是如何使用拦截器记录方法内部可能出现的信息日志呢? 我想在每个需要记录日志的 class 中实现一个空的 Log() 方法,该方法接受抽象日志信息作为参数。因此,如果用户需要记录任何信息,他可以调用此方法并提供日志内容。当调用此方法时,拦截器可以拦截并根据参数与其他方法区分开来。随后,信息将被记录下来,而调用者无需依赖记录器接口。

我唯一担心的是我可能会违反原则?或者还有什么需要考虑的吗?

public class Foo 
{    
    public void someMethod()
    {
        // do stuff
        this.Log(new MyLog("Log this information"));
        // do stuff
    }

    private void Log(ILog mylog) { }
}


public Interface ILog
{
    string Message;
    Exception Ex;
    LogLevel level;
    // anything worth logging
}

But how do I log with an interceptor information logs that might occur inside the method?

这是一个不适合拦截的场景(包括动态拦截和装饰)。在这种情况下,最好的方法是使用构造函数注入将日志记录抽象注入 class:

public class Foo 
{
    private readonly ILog log;

    public Foo(ILog log) => this.log = log;

    public void someMethod()
    {
        // do stuff
        this.log.Log(new MyLog("Log this information"));
        // do stuff
    }
}

虽然您可以使用可以使用动态代理框架实现的虚拟 Log 方法来实现这一点,但与简单地将 Volatile Dependency 注入构造函数相比,这会增加更多的复杂性。还要考虑如何测试这些日志记录调用。出于测试目的,您必须创建组件的派生实现。

但在将记录器注入您的消费者之前,请问问自己:Do I log too much?

另请注意,the second edition of Dependency Injection in .NET 详细介绍了好的和坏的日志记录策略,并提供了动态拦截的替代方法(第 10 章)。