我正在尝试使用 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 生成一个代理,然后将它们单独注册到容器中,然后才能使用它们?
我一直在通过随附的单元测试来尝试弄清楚它,但我正在努力理解它是如何工作的。
谢谢
我将添加到目前为止的答案,因为它确实在某种程度上回答了我的问题,尽管需要一些工作才能使其更加通用。我不知道如何将这种模式应用于程序集中的每个 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 需要的容器中注册的东西,所以我只是解决它,然后将其传递给工厂方法。
无论如何似乎都有效。如果有人可以建议如何使其更通用,那将是很棒的,但至少我认为这回答了我提出的问题。
Castle.Core.AsyncInterceptor nuget 包含一个扩展方法
Castle.DynamicProxy.ProxyGeneratorExtensions.ToInterceptor(this IAsyncInterceptor interceptor)
可以将异步拦截器转换为同步拦截器。似乎无法使用实例进行注册,您需要以其他方式进行注册。也许有可能
- 将拦截器注册为命名组件并使用拦截器引用
- 只是为了创建一个将异步拦截器转换为同步拦截器的适配器
我已经使用了适配器,它似乎工作正常。
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);
}