gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 23:14:12 26 4
gpt4 key购买 nike

使用 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com