注册/使用 Castle.Core.AsyncInterceptor 拦截器

Posted

技术标签:

【中文标题】注册/使用 Castle.Core.AsyncInterceptor 拦截器【英文标题】:Registering/Using Castle.Core.AsyncInterceptor Interceptors 【发布时间】:2020-05-09 13:44:30 【问题描述】:

我正在尝试使用 Castle.Core.AsyncInterceptor 包来处理异步方法引发的异常,但我很难理解如何将它们链接在一起。

我之前的 ExceptionInterceptor 实现了标准的 IInterceptor 接口,所以我可以使用类似的东西将拦截器应用于所有相关类

  _container.Register(Classes.FromAssemblyContaining(typeof(BaseDao))
                            .BasedOn<BaseDao>()
                            .Configure(c => c.Interceptors<ExceptionInterceptor>()));

文档建议改为实现 IAsyncInterceptor,我已经这样做了,但是上面代码中的最后一行现在可以理解地给我一个编译错误(没有从 ExceptionInterceptor 到 IInterceptor 的隐式引用转换),因为它不再是 IInterceptor。

相反,文档建议这样做

var myClass = new ClasThatImplementsIMyInterface();
var generator = new ProxyGenerator();
var interceptor = new ClasThatImplementsIAsyncInterceptor();
IMyInterface proxy = generator.CreateInterfaceProxyWithTargetInterface<IMyInterface>(myClass,interceptor)

但我不知道在那之后该怎么做。我是否必须为每个 DAO 生成一个代理,然后在容器中单独注册它们,然后才能使用它们?

我一直在通过随附的单元测试试图弄清楚它,但我很难理解它是如何工作的。

谢谢

【问题讨论】:

【参考方案1】:

我将添加到目前为止的答案,因为它确实在一定程度上回答了我的问题,尽管需要一些工作以使其更通用。我不知道如何将此模式应用于程序集中的每个 DAO,但至少它适用于一个类。我只需要为每个要添加拦截器的类重复此操作。

_container.Register(
          Component.For<IGroceryDao>()
              .UsingFactoryMethod(() => ServiceFactory.BuildGroceryDao(_container.Resolve<IDbTransaction>()))
              .LifestyleScoped());

它使用 ServiceFactory 中的工厂方法(只是我创建的一个包含以下方法的类)来创建已应用拦截器的代理 DAO:

public static IGroceryDao BuildGroceryDao(IDbTransaction transaction)
    
      return (IGroceryDao) new ProxyGenerator()
                                .CreateInterfaceProxyWithTargetInterface<IGroceryDao>(new Neo4jGroceryDao(transaction), new ExceptionInterceptor());
    

事务对象是已经在 DAO 需要的容器中注册的东西,所以我只需解析它,然后将它传递给工厂方法。

似乎仍然有效。如果有人可以建议如何使这个更通用,那就太棒了,但至少我认为这回答了我提出的问题。

【讨论】:

【参考方案2】:

Castle.Core.AsyncInterceptor nuget 包含一个扩展方法

Castle.DynamicProxy.ProxyGeneratorExtensions.ToInterceptor(this IAsyncInterceptor interceptor)

可以将异步拦截器转换为同步拦截器。似乎无法使用实例进行注册,您需要以其他方式进行。有可能

将拦截器注册为命名组件并使用 InterceptorReferences 只是为了创建一个将异步拦截器转换为同步拦截器的适配器

我已经使用了适配器,它似乎工作正常。

internal class MyInterceptorAdapter : IInterceptor 
  private readonly IInterceptor inner;

  public MyInterceptorAdapter(SomeDependency dep) 
    inner = new MyAsyncInterceptor(dep).ToInterceptor()
  

  public void Intercept(IInvocation invocation) 
       => inner.Intercept(invocation);

【讨论】:

以上是关于注册/使用 Castle.Core.AsyncInterceptor 拦截器的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 QtDbus 注册接口和注册方法?

ChatGPT注册和API使用(帮注册)--- 第一篇 注册

GCM 3.0:新注册不会过期使用 GCMRegistrar 注册的令牌

注册全局组件和局部组件

ansible变量注册多种方式

使用Nacos注册中心