c# - 使用 Simple Injector 的方法级属性拦截

标签 c# dependency-injection ioc-container simple-injector

使用 Unity,我可以像这样快速添加基于属性的拦截

public sealed class MyCacheAttribute : HandlerAttribute, ICallHandler
{
   public override ICallHandler CreateHandler(IUnityContainer container)
   {
        return this;
   }

   public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
   {
      // grab from cache if I have it, otherwise call the intended method call..
   }
}

然后我用这种方式注册Unity:

container.RegisterType<IPlanRepository, PlanRepository>(
    new ContainerControlledLifetimeManager(),
    new Interceptor<VirtualMethodInterceptor>(),
    new InterceptionBehavior<PolicyInjectionBehavior>());

在我的存储库代码中,我可以有选择地修饰某些要缓存的方法(具有可以为每个方法单独定制的属性值):

    [MyCache( Minutes = 5, CacheType = CacheType.Memory, Order = 100)]
    public virtual PlanInfo GetPlan(int id)
    {
        // call data store to get this plan;
    }

我正在探索在 Simple Injector 中执行此操作的类似方法。从我阅读和搜索的内容来看,似乎只有接口(interface)/类型级别的拦截可用。但我喜欢用这种类型的属性控制拦截行为来装饰单个方法的选项。有什么建议吗?

[编辑:将 Autofac 移至其 own question保持这个问题的重点]

最佳答案

Simple Injector 没有开箱即用的动态拦截支持,因为这不符合其设计原则,如 here 所述.然而,可以添加拦截功能,例如使用 CaSTLe DynamicProxy,如图所示 here .也应该可以在 Simple Injector 之上使用 Unity 的拦截功能,但我从未尝试过。

但是,当使用 DynamicProxy 时,您必须将拦截器类与属性类分开。这实际上是一个更好的做法,因为这会保留您的属性 passive并防止强制您的代码库依赖于拦截库。

使用 DynamicProxy 实现时,它可能看起来像这样:

public class MyCacheInterceptor : IInterceptor 
{   
    public void Intercept(IInvocation invocation) {
        var attribute = invocation.Method.GetAttribute<MyCacheAttribute>();

        if (attribute == null) {
            // Pass through without applying caching
            invocation.Proceed();
        } else {
           // apply caching here
        }
    }
}

然而,Simple Injector 通过应用 SOLID 原则并使用装饰器来促进面向方面的编程。在我编写的应用程序中,我定义了通用抽象,例如 ICommandHandler<TCommand>IQueryHandler<TQuery, TResult> .这使得通过装饰器应用缓存变得微不足道。装饰器的优点在于它们更简洁(因为它们不依赖任何外部库)并且性能更高。

关于c# - 使用 Simple Injector 的方法级属性拦截,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28953684/

相关文章:

c# - 命名空间更改后的 DataContractSerializer 兼容性

c# - 从 <div class =""> </div> 标签中提取内容 C# RegEx

c# - 从 ASP.NET Core 中的方法属性访问泛型类参数 T

android - Hilt - CoroutineDispatcher 上缺少绑定(bind)

c# - LINQ 到 SQL : Grouping and limiting a record set

c# - 私有(private)静态依赖与私有(private)依赖

forms - 是否可以使用 scaldi 依赖注入(inject)注入(inject) scala 对象?

asp.net-mvc - 应用程序池回收后 Autofac 无法解决

c# - 使用 CommonServiceLocator 将依赖项注入(inject)基类是一种好习惯吗?

.net - 国际奥委会会解决我们的问题吗?