object к хендлеру, хотя в дебагере видно, что получается нормальный хендлер, я получаю InvalidCastException. Ошибка происходит тут:
return ((IHandler<IRequest<TResponse>, TResponse>)handler).HandleAsync(request);
Подсмотрел как, это реализовано у Богарда, там используются врапперы, подскажите, пожалуйста, почему не проходит каст и что стоит по этому поводу почитать?
Метод, где происходит ошибка:
public Task<TResponse> Send<TResponse>(IRequest<TResponse> request)
{
var requestType = request.GetType();
if (!_handlerInfos.ContainsKey(requestType))
{
throw new InvalidOperationException($"No handler found for {requestType.FullName}");
}
var handlerType = _handlerInfos[requestType];
var handler = _serviceResolver.Invoke(handlerType);
return ((IHandler<IRequest<TResponse>, TResponse>)handler).HandleAsync(request);
}
Полный код класса
Просто навскидку: ты уверен что var handler имеет тип object?
А скрин с дебаггера дай
Да, он тут правильно себя ведет. Ты пытаешься скастить PrintTextHandler : IHandler<PrintTextRequest, bool> к IHandler<IRequest<TResponse>, TResponse> Но вот в чем дело: первый IHandler не работает с IRequest<TResponse>. Он работает с PrintTextRequest. Другими словами, ты не можешь ему передать просто IRequest<TResponse>, только PrintTextRequest, который является более узким подмножеством. Поэтому он должен либо у тебя быть IHandler<IRequest<bool>, bool>, либо ты должен вводить новый генерик тип, которому в данном случае будет подставляться PrintTextRequest, и кастовать к IHandler<SpecificRequestType, TResponse>
смахивает на дикий оверхед)0
Где именно?
ну на том сообщении
я пытаюсь вникнуть, слишком много буковок
Если вкратце, то ты кастишь Interface<V> к Interface<T>, где V (твой PrintRequest) наследник T. Так как тип заявляет что работает только с V, ты не можешь его скастовать к типу, который работает со всеми T, а в системе типов именно так и получается.
Спасибо большое, буду думать как лучше сделать. Кастить к IHandler<IRequest<bool>, bool> не вариант, а вот с доп. дженериком попробую что-то придумать
Еще вариант, который очевидно будет работать class ExampleHandler : IHandler<IRequest<bool>, bool> { public bool Execute(IRequest<bool> request) { return true; } }
Ну собственно я сделал практически тоже самое, о чем говорил Etki
Обсуждают сегодня