2014-11-04 88 views
1

我正在嘗試爲C#中的API調用構建可重用模塊。我想用這幾個不同的API。但是我無法動態地將我的數據類作爲變量傳遞給處理API調用的函數。例如,我打電話給兩個完全不同的API,我們將它們稱爲「Api#1」和「Api#2」。我有以下類:將數據類作爲變量傳遞給函數

// This is the format of the response from Api #1 GET 
public class Api01Get 
{ 
    public int orderId { get; set; } 
    public DateTime orderDate { get; set; } 
} 

// This is the format of the response from Api #2 GET 
public class Api02Get 
{ 
    public bool isGreen { get; set; } 
    public string name { get; set; } 
} 

這是對我的函數的調用。它工作正常,如果我使用我的一個數據類直接像這樣:

var result = CallAPI<Api02Get>(baseAddress, requestUri); 

但是,這不允許我靈活性我後。

這裏是我的函數的定義(我已經離開了這裏的其他參數不影響東西):

private async Task<TResult> CallAPI<TResult>(Uri baseAddress, string requestUri) 
{ 
    using (var client = new HttpClient()) 
    { 
     client.BaseAddress = baseAddress; 
     client.DefaultRequestHeaders.Accept.Clear(); 
     client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

     HttpResponseMessage response = new HttpResponseMessage(); 
     response = await client.GetAsync(requestUri); 
     if (response.IsSuccessStatusCode) 
     { 
      TResult result = await response.Content.ReadAsAsync<TResult>(); 
     } 
    } 

    // do other stuff... 

    return result; 
} 

現在,這是我掛了。我必須以不正確的方式來思考這一點,但我試圖做的就是這樣的事情,例如:

object apiModel; 

switch (whichAPI) 
{ 
    case "API_01_GET": 
     apiModel = new Api01Get(); 
     break; 

    case "API_02_GET": 
     apiModel = new Api02Get(); 
     break; 

    // Other cases... 

    default: 
     break; 
}  

var result = CallAPI<apiModel>(baseAddress, requestUri); 

試圖在最後一行時,我得到一個錯誤。 「無法找到類型或名稱空間名稱'apiModel'(您是否缺少using指令或程序集引用?)」。我嘗試了其他的東西,但這是最接近我的版本,所以這是我發佈的版本。

所以我不確定如何做到這一點,或者也許有更好的方法。我很感激任何反饋,如果有必要,我們很樂意澄清。提前致謝。

+0

這不會幫助你的設計問題,但你得到這個錯誤的原因是因爲'apiModel'不是一個類型,它是一個對象。試試'apiModel.GetType()'。 (我不是100%肯定會起作用) – MikeH 2014-11-04 21:22:06

+2

如果你能得到這個編譯和書面工作,接下來會發生什麼?在編譯時,你仍然不知道'result'變量指向的對象的類型,所以你不能對它做任何有意義的事情。 – Jay 2014-11-04 21:30:03

+0

@MikeH謝謝你,我最終聲明'輸入apiModel'而不是'object apiModel'。 ''apiModel.GetType()'沒有給我我想要的東西。 – RJD 2014-11-05 15:57:24

回答

0

不幸的是,如果沒有一些額外的反射來動態調用CallAPI<T>,則不能使用泛型。

幸運的是,HttpContentExtensions有額外的重載,這將允許您通過Type。你只需要超載你的方法,並對ReadAsAsync做一個小調整。

private async Task<object> CallAPI(Uri baseAddress, string requestUri, Type apiType) 
{ 
    using (var client = new HttpClient()) 
    { 
     .... 

     if (response.IsSuccessStatusCode) 
     { 
      object result = await response.Content.ReadAsAsync(apiType); 
     } 
    } 

    .... 

    return result; 
} 

您可能仍然需要,因爲你被卡住object向這雖然之前更改了一些你的代碼。