2015-04-21 40 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>

如何在不知道類型的情況下從結果中返回任務?

這是調用通用的代碼類型

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>暴露任務?如果我從Task更改爲普通Task,則不起作用。它仍然是一個任務,所以WebApi應該能夠用一些魔法來解決這個問題?我想要這個

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

現在它返回一個任務這也需要更新,請參閱調用者代碼的更新 – Anders

+0

是否有任何理由宣佈它返回'任務'vs普通的舊'任務'? –

+0

你不能有返回值?當這樣做時WebApi沒有顯示任何東西 – Anders

回答

1

這個問題有點令人困惑。特別不清楚錯誤信息來自哪裏。根據您發佈的小代碼,我認爲唯一有意義的事情是您實際上在Invoke()方法的return聲明中收到了該錯誤消息。即handler.Handle(query as dynamic)返回Task<System.Collections.Generic.IEnumerable<Customer>>類型的對象。這當然不會與Task<object>相同,因此是非法的。

如果我理解正確的話,那麼在我看來,你可以通過改變你的Invoke()方法本身解決的問題是async,這樣就可以在Task<object>Result而不是Task<System.Collections.Generic.IEnumerable<Customer>>重新包裝最終退回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

這個工程,其實與Solal Pirellis一樣的答案。這是什麼樣的包裝呢?它會導致一個只將舊結果轉換爲對象的同步任務嗎? WebAPI不處理實際任務的非通用任務是否有原因? – Anders

+0

我會將此標記爲答案,但我的實際問題是,如果我可以使WebApi與任務一起工作作爲任務暴露,這裏的新問題http://stackoverflow.com/questions/29769261/return-taskt-as-plain- task-breaks-webapi – Anders

+0

_「這是什麼包裝它的樣子」_ - 我會說「最小」。該操作仍然是異步的,只不過是在調用堆棧中向下執行延續。你最終得到了中間的'Task'對象,但是我認爲這是不可避免的,因爲這個問題:你需要(顯然)從預定義的API返回一個異步'對象',但是你的底層API返回一個特定的類型。在某些時候,具體類型必須在相應的'Task '類型中解包並重新包裝。額外的對象是最小的開銷。 –

1

你這裏的問題是,Task<T>不是協變的,即你不能隱式轉換Task<Something>Task<object> - 不同,例如,從IEnumerable<Something>轉換到IEnumerable<object>

解決這個問題的最簡單的方法是改變你Get方法await任務,並在兩個單獨的語句返回值,就像這樣:

object obj = await ...; 
return obj;