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
,但同样适用于 OnExit
和 OnException
。
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
.
我想在我的 Blazor Server .NET 5 (C# 9) 应用程序中实现和使用 AOP 日志记录,用于标记方法的一般进入-退出-异常场景。
我知道如何使用 MethodBoundaryAspect.Fody NuGet 包和自定义属性,但是使用依赖注入我无法将 ILogger 注入自定义属性(其生命周期也不受内置服务提供商控制) ,所以这似乎不再是一个可行的解决方案。我不坚持使用 Attribute 作为解决方案,它看起来非常实用。
我的总体目标是摆脱产品方法中一般登录的样板代码行。使用另一个属性(或其他属性)测量经过的时间对于所需的解决方案来说将是小菜一碟。
确实不能使用依赖注入将服务注入到属性的构造函数中。考虑到它们代表 compile-time 元数据,这不足为奇。
但是,如果我们后退一步,我们可以利用接口结合传递给您的信息 method interceptors。我们将专注于 OnEntry
,但同样适用于 OnExit
和 OnException
。
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
.