2014-11-04 5 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; } 
} 

다음은 my 함수 호출입니다.

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'을 찾을 수 없습니다 (사용 지시문이나 어셈블리 참조가 누락 되었습니까?)". 나는 다른 것들을 시도했지만 이것은 내가 가장 가까이에있는 것처럼 보이는 버전이므로 이것이 내가 게시 한 것이다.

그래서 이것을 수행하는 방법이 확실하지 않거나 더 좋은 방법이있을 수 있습니다. 의견을 보내 주시면 감사 드리며 필요한 경우 알려 드리겠습니다. 미리 감사드립니다.

+0

이것은 디자인 문제를 해결하는 데 도움이되지 않지만 'apiModel'유형이 아니기 때문에 오류가 발생하는 이유는 객체입니다. 'apiModel.GetType()'을 시도하십시오. (저는 100 % 확신 할 수 없습니다.) – MikeH

+2

이것을 컴파일하고 서면으로 작업 할 수 있다면 다음에 어떤 일이 일어날까요? 컴파일 타임에'result' 변수가 가리키는 객체의 유형을 알지 못하기 때문에 의미있는 일은 할 수 없습니다. – Jay

+0

@MikeH 고맙습니다. 결국'object apiModel' 대신'Type apiModel'을 선언했습니다. 그리고'apiModel.GetType()'은 내가 원한 것을주지 않았습니다. – RJD

답변

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 붙어 있기 때문에이 생각하기 전에 코드의 일부를 변경해야 할 수 있습니다.

관련 문제