Асинхронный перехват с использованием динамического прокси 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 ответ
Я решил это в конце концов с помощью нескольких модификаций:
Создав перехватчик с базовым объектом, я использовал объекты Moq, чтобы лениво создавать их и сохранять в ConcurrentDictionary для кэширования.
var mock = new Mock<T>(); var pg = new ProxyGenerator(); return pg.CreateInterfaceProxyWithTarget<T>(GetTarget(clientType), _gatewayInterceptor);
Я передал возвращаемое значение вызова (в этом случае Задача T) методу и получил T.
- Я завернул вызов http новой задачей T, дождался вызова http и возвратил десериализованный результат T из задачи.
Присвойте новую задачу 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