与Microsoft.Extensions.DependencyInjection和asp.net Web API 2的拦截器,可解决诸如日志记录之类的交叉问题

azh*_*ani 5 c# aop dependency-injection cross-cutting-concerns asp.net-web-api

我们在asp.net Web api2中使用Microsoft.Extensions.DependencyInjection进行依赖项注入。

对于诸如日志记录之类的跨领域问题,我们认为应该考虑面向方面的编程,并且在上面的di中找不到任何支持。

其他的DI,例如Castle,Unity和ninject则选择退出以查看其基准。有没有办法使用其他di框架的注入器(例如城堡动态代理)并将其与microsoft.extensioins.dependencyinjection结合使用?

也欢迎任何有关编织框架的建议。由于不是免费的,排除了考虑后期处理的问题。

Lau*_*kas 6

Decor.NET是动态代理的包装器Castle.Core,旨在简化方法装饰。

它与 DI 容器无关,但与 Microsoft 的 DI 集成,可在Decor.Extensions.Microsoft.DependencyInjectionNuGet 包中找到。

  1. 您创建一个装饰器:

    public class YourDecorator : IDecorator
    {    
        public SomeDependency SomeDependency { get; }    
    
        public YourDecorator(SomeDependency someDependency) // Supports DI.
        {
            SomeDependency = someDependency;
        }
    
        public async Task OnInvoke(Call call)
        {
            ...
            await call.Next();
            ...
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 装饰你的方法:

    [Decorate(typeof(YourDecorator))]
    virtual void SomeMethod()  // << has to be overridable (can come from an interface)
    {
        ...
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在 Microsoft 的 DI 中注册所有内容:

    services.AddDecor()
        .AddTransient<YourDecorator>()
        .AddScoped<YourService>().Decorated();
    
    Run Code Online (Sandbox Code Playgroud)

您可以在这个.Net Fiddle中玩耍。


披露:我是这个包的作者。

  • 难道不是不必向现有类添加属性或记住添加到所有现有或新类吗?此外,如果该库用于其他项目(即网络与服务),我不想修改每个类。我有许多在不同上下文中使用的大型项目库。我想将所有调用包装在计时器中,并记录超过特定阈值的调用。我不想去修改每个库中的所有类。我想使用 DI 框架通过我的“方面”(每个方法的运行时的计时器和日志)来检测每个类。谢谢。 (3认同)

Pet*_*ons 0

我不相信在开发 Web api 时您需要像 PostSharp 这样的工具或任何其他 AOP 工具。有许多扩展点,您可以在其中插入日志记录/审核/任何操作。这张海报是一个很好的概述

您可以创建一个操作过滤器。例如,您可以在所有控制器(如果需要)或MessageHandler中全局注册它。

现在,针对您的评论:

[..] 登录业务层/数据访问层的类(如任何异常/自定义消息)而不直接调用记录器怎么样?[..]

我不确定你想通过这个实现什么目的。如果您有适当的异常处理,则必须处理异常或让它冒泡。在编写异常处理时,为什么不额外编写一行来记录您需要的任何内容呢?它使您有机会向日志消息添加有意义的上下文,这是使用自动化 AOP 工具很难做到的!

最后,让我谈谈这个评论:

排除了 PostSharp 的考虑,因为它不是免费的。

像 PostSharp 这样的工具如果能够解决手头的问题,就非常非常值得。当然,您可以花一天时间研究免费替代方案或编写自己的实现,但它可能会受到更多限制,需要重构现有代码库,整个团队难以维护,并且会消耗大量时间。替代方案可能比该工具更昂贵。

  • 我同意你的观点。但是,日志记录仅限于控制器。登录业务层/数据访问层的类(如任何异常/自定义消息)而不直接调用记录器怎么样?我找不到任何有关此类日志记录/横切问题的内容。我认为 Aop 可以通过注入日志代码来帮助我。 (4认同)