Асинхронный перехват с использованием динамического прокси Castle

Я пытаюсь построить динамический 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);
        });
    }

Моя задача возвращает динамический / объект, а не T типа возврата "Перехват".

Я думал, что смогу использовать это так

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

Так как задание, которое будет возвращено, является исходным заданием, и оно все еще находится в ожидании, я думал, что оно будет работать, но все, что я получаю, это исключение, что Задача не может быть преобразована в задание моего типа (которое в данном случае является строкой).

Спасибо за помощников

Изменить: я видел асинхронный метод Intercept, это то, что я пытался сделать, но я не смог вызвать задачу, даже используя отражение, я все еще получил то же исключение.

1 ответ

Решение

Я решил это в конце концов с помощью нескольких модификаций:

  1. Создав перехватчик с базовым объектом, я использовал объекты Moq, чтобы лениво создавать их и сохранять в ConcurrentDictionary для кэширования.

    var mock = new Mock<T>();
    var pg = new ProxyGenerator();
    return pg.CreateInterfaceProxyWithTarget<T>(GetTarget(clientType), _gatewayInterceptor);
    
  2. Я передал возвращаемое значение вызова (в этом случае Задача T) методу и получил T.

  3. Я завернул вызов http новой задачей T, дождался вызова http и возвратил десериализованный результат T из задачи.
  4. Присвойте новую задачу T обратно возвращаемому значению.

    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

Другие вопросы по тегам