Асинхронный перехват с использованием динамического прокси Castle - PullRequest
0 голосов
/ 11 сентября 2018

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

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

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

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

1 Ответ

0 голосов
/ 10 октября 2018

Я решил это в конце концов с несколькими модификациями:

  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

...