NET Core 2.1中使用AOP进行记录

use*_*305 4 c# logging aop asp.net-core asp.net-core-2.1

我想为.NET Core 2.1解决方案中的日志记录实现AOP。我以前从未使用过它,而我一直在网上寻找,似乎看不到任何有人在Core 2中使用它的示例。有人知道我会怎么做吗?

例如,哪些软件包可用于AOP,并有示例代码可帮助我入门?我使用带有.net核心的内置DI,因此我不必担心该部分。

小智 6

Microsoft DI不提供诸如拦截器或装饰器之类的高级方案(使用Microsoft DI的装饰器有一种解决方法:https : //medium.com/@willie.tetlow/net-core-dependency-injection-decorator-workaround-664cd3ec1246) 。

您可以通过使用Autofac(https://autofaccn.readthedocs.io/en/latest/advanced/interceptors.html)或带有动态代理的简单注入器来实现AOP 。两者都有非常好的文档。由于其设计规则,简单注入器没有开箱即用的解决方案,但是您可以为其添加扩展名(http://simpleinjector.readthedocs.io/en/latest/aop.html)。

这是来自官方SI文档的基本AOP场景:( http://simpleinjector.readthedocs.io/en/latest/InterceptionExtensions.html):

//Add registration to the composition root
container.InterceptWith<MonitoringInterceptor>(serviceType => serviceType.Name.EndsWith("Repository"));`

// Here is an example of an interceptor implementation.
// NOTE: Interceptors must implement the IInterceptor interface:
private class MonitoringInterceptor : IInterceptor {
    private readonly ILogger logger;

  public MonitoringInterceptor(ILogger logger) {
        this.logger = logger;
    }

    public void Intercept(IInvocation invocation) {
        var watch = Stopwatch.StartNew();

        // Calls the decorated instance.
        invocation.Proceed();

        var decoratedType = invocation.InvocationTarget.GetType();

        this.logger.Log(string.Format("{0} executed in {1} ms.",
            decoratedType.Name, watch.ElapsedMilliseconds));
    }
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*rry 6

免责声明:我是该解决方案的制作者

Microsoft 没有Net Core 提供开箱即用的 AOP 解决方案。不过,我制作了一个可能有帮助的第三方项目。它直接与 Net Core 配合使用,并通过应用程序中的 ServiceCollection 注册进行插入。

Microsoft 确实提供了一个名为 System.Runtime.DispatchProxy 的库,它可用于为您的类创建代理对象。然而,这个代理本身并不是特别有用或功能丰富,并且需要大量额外的代码才能获得与 Castle Proxy(众所周知的动态代理库)处于同一水平的东西

考虑到这一点,我创建了一个库,它将 DispatchProxy 包装到可以在应用程序启动的 ServiceCollection 配置期间轻松注入的代码中。诀窍是有一种方法来创建属性和一个可以应用于您的方法的配对拦截器。然后在代理包装期间读取该属性并调用相关的拦截器。

这是拦截器属性的示例

public class ConsoleLogAttribute : MethodInterceptorAttribute
{
}
Run Code Online (Sandbox Code Playgroud)

这是拦截器类的示例

public class ConsoleLogInterceptor : MethodInterceptor
{
    public override void BeforeInvoke(IInterceptionContext interceptionContext)
    {
        Console.WriteLine($"Method executing: {interceptionContext.CurrentMethod.Name}");
    }

    public override void AfterInvoke(IInterceptionContext interceptionContext, object methodResult)
    {
        Console.WriteLine($"Method executed: {interceptionContext.CurrentMethod.Name}");
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是它将如何应用于您的方法

[ConsoleLog]
public void TestMethod()
{
}
Run Code Online (Sandbox Code Playgroud)

最后,这就是将其添加到 ServiceCollection 配置中的方式(假设您想要代理的类名为 [TestClass]:

public void ConfigureServices(IServiceCollection services)
{
    // Configure Simple Proxy
    services.EnableSimpleProxy(p => p.AddInterceptor<ConsoleLogAttribute, ConsoleLogInterceptor>());

    // Configure your services using the Extension Methods
    services.AddTransientWithProxy<ITestClass, TestClass>();
}
Run Code Online (Sandbox Code Playgroud)

看看这个 GitHub 项目:https ://github.com/f135ta/SimpleProxy