使用 Castle 动态代理的异步拦截

Async Interception using Castle dynamic proxy

我正在尝试使用动态代理构建一个动态 http 客户端来拦截调用并使用它创建一个 http 请求。

我遇到的问题是异步方法:

private Task<object> PostAsync(HttpClient client, string url, HttpRequestParameters parameters, Type returnType)
    {
        return Task.Run(async () =>
        {
            var requestContent = new StringContent(Serializer.Serialize(parameters.BodyParameters));
            var httpResponse = await client.PostAsync(url, requestContent);
            var responseContent = await httpResponse.Content.ReadAsStringAsync();
            return Serializer.Deserialize(responseContent, returnType);
        });
    }

我的任务 returns dynamic/object 而不是拦截 return 类型的 T。

我以为我可以像这样使用它

 var task = PostAsync(client, url, parameters, returnType);
 invocation.ReturnValue = task;

由于将 returned 的任务是原始任务并且它仍在等待中,我认为它可以工作但我得到的只是一个例外,即任务无法转换为我的类型的任务(在那种情况下是字符串)。

感谢帮手

编辑: 我确实看到了 ,这就是我尝试做的,但即使使用反射我也无法调用任务,我仍然遇到同样的异常。

我最终通过一些修改解决了它:

  1. 使用基础对象创建拦截器,我使用 Moq 对象来延迟创建它们并将它们存储在 ConcurrentDictionary 中以进行缓存。

    var mock = new Mock<T>();
    var pg = new ProxyGenerator();
    return pg.CreateInterfaceProxyWithTarget<T>(GetTarget(clientType), _gatewayInterceptor);
    
  2. 我将调用的 return 值(在那种情况下是 T 的任务)传递给方法并获得了 T。

  3. 我用 T 的新任务包装了 http 调用,等待 http 调用并 return 反序列化任务的 T 结果。
  4. 将T的新任务分配回return值。

    invocation.ReturnValue = GetAsync((dynamic)invocation.ReturnValue, serializer, headers, req);
    
    internal static Task<T> GetAsync<T>(Task<T> originalTask, ISerializer serializer, Headers headers, InvokeHttpRequest req)
    {
        return Task.Run(async () =>
        {
            using (HttpClient client = new HttpClient())
            {
                var httpResponse = await PerformGetAsync(headers, req, client);
                var jsonResponse = await httpResponse.Content.ReadAsStringAsync();
                return ProcessResult<T>(serializer, jsonResponse);
            }
        });
    }
    

我知道这不是最好的方法,但它对我有用。 如果有人需要,解决方案就在这里 https://github.com/ErezLevip/SimpleProxyClient