castle 动态代理(异步)

 castle 异步方法拦截可以参见  https://github.com/castleproject/Core/issues/107

一 接口异步的,拦截器非异步

复制代码
    public interface IAsyncTInterface
    {
        Task<string> TestAsyncMethod();
    }

    public class AsyncTarget : IAsyncTInterface
    {
        public async Task<string> TestAsyncMethod()
        {
            await Task.Delay(100);
            throw new Exception("Something failed, in target method");
        }
    }
复制代码

拦截器

复制代码
    public class MyInterceptor : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            invocation.Proceed();
            var returnValue = (Task<string>)invocation.ReturnValue;
            returnValue.ContinueWith(t =>
            {
                Console.WriteLine(t.Exception.Message);
                invocation.ReturnValue = Task.FromResult("result");
            }, TaskContinuationOptions.OnlyOnFaulted);
        }
    }
复制代码

代理对象

  var builder = new ContainerBuilder();
            builder.RegisterType<AsyncTarget>()
       .As<IAsyncTInterface>()
       .EnableInterfaceInterceptors().InterceptedBy(typeof(MyInterceptor));

二 异步拦截器 

castle拦截器没有实现对异步方法的拦截,异步方法拦截使用 Castle.Core.AsyncInterceptor 库来处理。Castle.Core.AsyncInterceptor库几个核心对象如下

IAsyncInterceptor 拦截器接口 ,AsyncDeterminationInterceptor充当适配器的角色,实现castle.core IInterceptor,方法执行会调用IAsyncInterceptor 。

实现步骤

  1.先定义一个对象继承AsyncInterceptorBase 

复制代码
    public class NewAsyncInterceptor : AsyncInterceptorBase
    {

        protected override async Task InterceptAsync(
            IInvocation invocation,
            IInvocationProceedInfo proceedInfo,
            Func<IInvocation, IInvocationProceedInfo, Task> proceed)
        {
            try
            {
                Console.WriteLine($"{invocation.Method.Name}:Starting Void Method");
                await proceed(invocation, proceedInfo).ConfigureAwait(false);
                Console.WriteLine($"{invocation.Method.Name}:Completed Void  Method");
            }
            catch (Exception e)
            {
                Console.WriteLine($"{invocation.Method.Name}:Throw Exception :{e.Message}");
                throw;
            }
        }

        protected override async Task<TResult> InterceptAsync<TResult>(
            IInvocation invocation,
            IInvocationProceedInfo proceedInfo,
            Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
        {
            try
            {
                Console.WriteLine($"{invocation.Method.Name}:Starting Result Method");
                TResult result = await proceed(invocation, proceedInfo).ConfigureAwait(false);
                Console.WriteLine($"{invocation.Method.Name}:Completed Result Method");
                return result;
            }
            catch (Exception e)
            {
                Console.WriteLine($"{invocation.Method.Name}: Throw Exception Result:{e.Message}");
                throw;
            }
        }
    }
复制代码

2.适配器实现 

      castle对于异步注入,使用autofac 暂时是不支持直接注入IAsyncInterceptor 的,如果使用autofac注入castle.core 需要适配器来处理。

复制代码
   public class AsyncInterceptorAdaper : AsyncDeterminationInterceptor
    {
        IAsyncInterceptor _asyncInterceptor;
        public AsyncInterceptorAdaper(IAsyncInterceptor Interceptor)
            : base(Interceptor)
        {
            _asyncInterceptor = Interceptor;
        }
        public override void Intercept(IInvocation invocation)
        {
            _asyncInterceptor.ToInterceptor().Intercept(invocation);
        }

    }
复制代码

3.注册

 var builder = new ContainerBuilder();
            builder.RegisterType<AsyncInterceptorAdaper>();
            builder.RegisterType<NewAsyncInterceptor>().As<IAsyncInterceptor>();

            builder.RegisterType<AsyncTarget>()
                    .As<IAsyncTInterface>()
                    .EnableInterfaceInterceptors().InterceptedBy(typeof(AsyncInterceptorAdaper));

 

泛型适配器

    public class AsyncInterceptorAdaper<TAsyncInterceptor> : AsyncDeterminationInterceptor
  where TAsyncInterceptor : IAsyncInterceptor
    {
        public AsyncInterceptorAdaper(TAsyncInterceptor asyncInterceptor)
            : base(asyncInterceptor)
        { }
    }
           var builder = new ContainerBuilder();
            builder.RegisterType<NewAsyncInterceptor>();
            builder.RegisterGeneric(typeof(AsyncInterceptorAdaper<>));
            builder.RegisterType<AsyncTarget>()
        .As<IAsyncTInterface>()
        .EnableInterfaceInterceptors().InterceptedBy(typeof(AsyncInterceptorAdaper<>).MakeGenericType(typeof(NewAsyncInterceptor)));

 

作者:RunStone

出处:https://www.cnblogs.com/RunStone/p/14362847.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   奔跑石头  阅读(992)  评论(1编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
more_horiz
keyboard_arrow_up light_mode palette
选择主题
点击右上角即可分享
微信分享提示