2015-04-21 2 views
1

я работаю на асинхронном CQS APIзадачи с результатом неизвестного типа

Метод WebAPI выглядит следующим образом

public async Task<object> Get([FromUri] Contract contract) 
{ 
    return await _invoker.Invoke(CreateDto<Query>(contract)); 
} 

Не может неявно преобразовать тип «System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<Customer>>» к 'System.Threading.Tasks.Task<object>

Как я могу вернуть задачу из результата, не зная тип?

Это код, который вызывает Generic набран класс

public Task<object> Invoke(Query query) 
{ 
    var queryHandlerType = typeof(IQueryHandler<,>); 
    var queryType = query.GetType(); 
    var queryResultType = queryType.BaseType.GetGenericArguments().First(); 
    var handler = _container.GetInstance(queryHandlerType.MakeGenericType(queryType, queryResultType)) as dynamic; 
    return handler.Handle(query as dynamic); 
} 

редактировать: Есть ли причина, почему WebAPI не поддерживает Task<T> представленные как Задачу? Если я перейду из задачи в простое задание, это не сработает. Его все еще задача под тем, чтобы WebApi должен был решить это с помощью какой-то магии? Я хочу сделать это

public Task Get([FromUri] Contract contract) 
{ 
    return _invoker.Invoke(CreateDto<Query>(contract)); 
} 
+0

сейчас она возвращает Task , который также должен быть обновлено, см. обновление для кода invoker – Anders

+0

Есть ли причина, по которой было объявлено о возврате 'Task ' против простой старой 'Задачи'? –

+0

Вы не можете вернуть значения? WebApi ничего не делает, когда делает это так: – Anders

ответ

1

Вопрос немного запутанный. Особенно непонятно, откуда приходит сообщение об ошибке. Исходя из небольшого кода, который вы опубликовали, единственное, что я вижу, имеет смысл, так это то, что вы действительно получаете это сообщение об ошибке в инструкции return вашего метода Invoke(). То есть что handler.Handle(query as dynamic) возвращает объект типа Task<System.Collections.Generic.IEnumerable<Customer>>. Это, конечно, не будет таким же, как Task<object>, и поэтому было бы незаконным.

Если я правильно понимаю, то мне кажется, вы могли бы решить проблему, изменив себя ваш метод Invoke() быть async, так что вы можете обернув в конечном счете, возвращенное System.Collections.Generic.IEnumerable<Customer> объект в Result в виде Task<object> вместо Task<System.Collections.Generic.IEnumerable<Customer>> что в настоящее время создается:

public async Task<object> Invoke(Query query) 
{ 
    var queryHandlerType = typeof(IQueryHandler<,>); 
    var queryType = query.GetType(); 
    var queryResultType = queryType.BaseType.GetGenericArguments().First(); 
    var handler = _container.GetInstance(queryHandlerType.MakeGenericType(queryType, queryResultType)) as dynamic; 
    return await handler.Handle(query as dynamic); 
} 


Если это не решает вашу конкретную озабоченность, пожалуйста, измените вопрос так, что это более ясно. Пожалуйста, предоставьте a good, minimal, complete code example, который надежно воспроизводит проблему.

+0

Это работает, и на самом деле тот же ответ, что и Солал Пиреллис. Какая-то интрактная упаковка? Это приведет к задаче синхронизации, которая просто возвращает старый результат объекту? Есть ли причина, почему WebAPI не обрабатывает негенерические задачи, которые являются актуальными Задача ? – Anders

+0

Я отмечу это как ответ, но мой фактический вопрос заключается в том, могу ли я сделать работу WebApi с Задачей открытой как Задача, новый вопрос здесь http://stackoverflow.com/questions/29769261/return-taskt-as-plain- task-breaks-webapi – Anders

+0

_ «Что такое вложение в нее?» - я бы сказал «минимальный». Операция по-прежнему асинхронна, это просто, что продолжение реализовано на одном уровне вниз в стеке вызовов. Вы заканчиваете промежуточный объект «Задача», но я вижу это как неизбежное из-за проблемы: вам требуется (по-видимому) вернуть асинхронный «объект» из предопределенного API, но ваш базовый API возвращает определенный тип , В какой-то момент конкретный тип должен быть развернут и переопределен в соответствующем типе 'Task '. Дополнительный объект - минимальные накладные расходы. –

1

Ваша проблема в том, что Task<T> не ковариантны, то есть вы не можете неявно преобразовать Task<Something> к Task<object> - в отличие, например, преобразование из IEnumerable<Something> к IEnumerable<object>.

Самый простой способ исправить это изменить метод Get на await задачу и возвращает значение в виде двух отдельных высказываний, например:

object obj = await ...; 
return obj; 
Смежные вопросы