Blazor Server如何进行AOP日志记录?

How Blazor Server AOP logging?

我想在我的 Blazor Server .NET 5 (C# 9) 应用程序中实现和使用 AOP 日志记录,用于标记方法的一般进入-退出-异常场景。

我知道如何使用 MethodBoundaryAspect.Fody NuGet 包和自定义属性,但是使用依赖注入我无法将 ILogger 注入自定义属性(其生命周期也不受内置服务提供商控制) ,所以这似乎不再是一个可行的解决方案。我不坚持使用 Attribute 作为解决方案,它看起来非常实用。

我的总体目标是摆脱产品方法中一般登录的样板代码行。使用另一个属性(或其他属性)测量经过的时间对于所需的解决方案来说将是小菜一碟。

确实不能使用依赖注入将服务注入到属性的构造函数中。考虑到它们代表 compile-time 元数据,这不足为奇。

但是,如果我们后退一步,我们可以利用接口结合传递给您的信息 method interceptors。我们将专注于 OnEntry,但同样适用于 OnExitOnException

public virtual void OnEntry(MethodExecutionArgs arg)
{
}

MethodExecutionArgs 有很多有用的属性,但我们只关注一个:Instance property。鉴于此 属性 表示包含被拦截方法的 class 的实例,您可以选择对 class 实现的接口进行一些假设。

如果你定义了一个新的接口,比如说 ILoggerProvider 你可以让包含你想要记录的方法的 class 实现这个接口来给你的方面一个 ILogger 的句柄:

public interface ILoggerProvider
{
    ILogger Logger { get; }
}

把这些放在一起,你的 class 应该像这样:

public class MyProduct : ILoggerProvider
{
    public ILogger Logger { get; }

    public MyProduct(ILogger logger)
    {
        Logger = logger;
    }

    [Log]
    public void M()
    {
    }
}

最后,您的外观应该类似于:

public class LogAttribute : OnMethodBoundaryAspect
{
    private ILogger GetLogger(MethodExecutionArgs args) => ((ILoggerProvider)args.Instance).Logger;

    public override void OnEntry(MethodExecutionArgs args)
    {
        var logger = GetLogger(args);
        // Log whaat you will
    }

    public override void OnExit(MethodExecutionArgs args)
    {
        var logger = GetLogger(args);
        // Log whaat you will
    }

    public override void OnException(MethodExecutionArgs args)
    {
        var logger = GetLogger(args);
        // Log whaat you will
    }
}

注意:这假设你要拦截的方法不是静态方法,因为它们显然会有一个null Instance.