私はこれをすべて抽象化しています。
私はサービスの抽象化を持つことになり、プレゼンテーション層で
...
public interface IServiceAgent {
Task<SomeResultObject> GetSomething(string myParameter);
}
...それは私がウェブAPIから欲しいものを抽象化します。発表者は要求を調整する必要はありません。発表者は、データがどこから来ているかには関心がありません。知っていることは、何かを求めてそれを求める(SoC)ということだけです。これを行うのはサービス代理店の仕事です(SRP)。
サービスエージェントの実装では、データのさまざまなソースへの呼び出しが必要な場合があります。ウェブを含む。したがって、HttpClient
を抽象化すると、その実装への結合が緩められます。とのユニットテストを可能にすることによって、あなたがテスト可能なプレゼンターを保つそれらの依存関係を抽象化し
簡単な例のように...
public interface IHttpClient {
System.Threading.Tasks.Task<T> GetAsync<T>(string uri) where T : class;
System.Threading.Tasks.Task<T> GetAsync<T>(Uri uri) where T : class;
//...other members as needed : DeleteAsync, PostAsync, PutAsync...etc
}
いくつかの実装例
はこのようになります...
public class MyPresenter {
public MyPresenter(IServiceAgent services) {...}
}
public class MyDefaultServiceAgent : IServiceAgent {
IHttpClient httpClient;
public MyDefaultServiceAgent (IHttpClient httpClient) {
this.httpClient = httpClient;
}
public async Task<SomeResultObject> GetSomething(string myParameter) {
var url = "http://localhost/my_web_api_endpoint?q=" + myParameter;
var result = await httpClient.GetAsync<SomeResultObject>(url);
return result;
}
}
public class MyDefaultHttpClient : IHttpClient {
HttpClient httpClient; //The real thing
public MyDefaultHttpClient() {
httpClient = createHttpClient();
}
/// <summary>
/// Send a GET request to the specified Uri as an asynchronous operation.
/// </summary>
/// <typeparam name="T">Response type</typeparam>
/// <param name="uri">The Uri the request is sent to</param>
/// <returns></returns>
public System.Threading.Tasks.Task<T> GetAsync<T>(string uri) where T : class {
return GetAsync<T>(new Uri(uri));
}
/// <summary>
/// Send a GET request to the specified Uri as an asynchronous operation.
/// </summary>
/// <typeparam name="T">Response type</typeparam>
/// <param name="uri">The Uri the request is sent to</param>
/// <returns></returns>
public async System.Threading.Tasks.Task<T> GetAsync<T>(Uri uri) where T : class {
var result = default(T);
//Try to get content as T
try {
//send request and get the response
var response = await httpClient.GetAsync(uri).ConfigureAwait(false);
//if there is content in response to deserialize
if (response.Content.Headers.ContentLength.GetValueOrDefault() > 0) {
//get the content
string responseBodyAsText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
//desrialize it
result = deserializeJsonToObject<T>(responseBodyAsText);
}
} catch (Exception ex) {
Log.Error(ex);
}
return result;
}
private static T deserializeJsonToObject<T>(string json) {
var result = JsonSerializer.Deserialize<T>(json);
return result;
}
}
擬似/模擬サービス代理店。あなたは、偽の/模擬HTTPクライアントを使ってサービスエージェントをテストすることができます。また、アプリケーションコンポーネントを変更/交換/維持する必要がある場合は、これらのインタフェースの具体的な実装を注入することもできます。
この質問はhttp://programmers.stackexchange.com/に属しているので、私はこのトピックをオフトピックとして閉じるよう投票しています。 –