【问题标题】:Interceptor with Microsoft.Extensions.DependencyInjection and asp.net web api 2 for cross cutting concerns like logging带有 Microsoft.Extensions.DependencyInjection 和 asp.net web api 2 的拦截器,用于横切关注点,例如日志记录
【发布时间】:2018-07-07 18:58:17
【问题描述】:

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

对于像日志这样的横切关注点,我们认为应该考虑面向方面的编程,在上述di中找不到任何支持。

Castle、Unity 和 ninject 等其他 DI 在查看其基准后选择退出。 有没有办法使用其他di框架的注入器,如城堡动态代理并将其与Microsoft.Extensions.DependencyInjection一起使用?

也欢迎任何与 IL 编织框架相关的建议。 PostSharp 的考虑被排除在外,因为它不是免费的。

【问题讨论】:

  • MS.DI 非常有限。虽然使用动态拦截库(例如 Castle Dynamic Proxy)应用拦截器并非完全不可能,但您应该考虑使用更成熟、功能更丰富的 DI Container。

标签: c# asp.net-web-api dependency-injection aop cross-cutting-concerns


【解决方案1】:

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

它与 DI 容器无关,但与 Microsoft 的 DI 集成,可在 Decor.Extensions.Microsoft.DependencyInjection NuGet 包中使用。

  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();
            ...
        }
    }
    
  2. 装饰你的方法:

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

    services.AddDecor()
        .AddTransient<YourDecorator>()
        .AddScoped<YourService>().Decorated();
    

你可以在这个.Net Fiddle玩。


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

【讨论】:

  • 是不是不必向现有类添加属性或记住添加到所有现有或新类?此外,如果该库用于其他项目(即 web 与服务),我不想修改每个类。我有许多在不同环境中使用的大型项目库。我想将所有呼叫包装在一个计时器中并记录超过某个阈值的呼叫。我不想去修改每个库中的所有类。我想使用 DI 框架用我的“方面”来检测每个类 - 每个方法运行时的计时器和日志。谢谢。
【解决方案2】:

我认为您不需要任何 AOP 框架,.NET 提供的工具足以让您自己完成大部分面向方面的工作。

简短的版本是这样的:

  1. 从 MarshalByRefObject 继承您的商务舱。

  2. 为您想要的功能创建一个“方面”。如,创建一个继承自RealProxy 的类。例如public class LoggingAspect&lt;T&gt; : RealProxy.

  3. 覆盖 Invoke 方法,并实现您的方面代码。确保将方法调用传递给原始实例。

  4. 创建一个构建器/工厂类,该类将创建所需类的实例,例如Entity e = EntityBuilder.WithLogging();

  5. 将new Entity(...) 的所有实例替换为EntityBuilder.Get(...)。

微软员工自己更好地解释了长版本:

Aspect-Oriented Programming : Aspect-Oriented Programming with the RealProxy Class

【讨论】:

    【解决方案3】:

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

    您可以创建一个Action Filter。例如,您可以register this globally across all controllers(如果需要)或MessageHandler。

    【讨论】:

    • 我同意你的看法。但是,日志记录仅限于控制器。在不直接调用记录器的情况下记录业务层/数据访问层的类(如任何异常/自定义消息)怎么样?我找不到任何可以解决此类日志记录/横切问题的信息。我认为 Aop 可以通过注入日志代码来帮助我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 2013-11-13
    相关资源
    最近更新 更多