一個簡單的例子:
// You need interface to keep your repository usage abstracted
// from concrete implementation as this is the whole point of
// repository pattern.
public interface IUserRepository
{
Task<User> GetUserAsync(int userId);
}
public class UserRepository : IUserRepository
{
private static string baseUrl = "https://example.com/api/"
public async Task<User> GetUserAsync(int userId)
{
var userString = await GetStringAsync(baseUrl + "users/" + userId);
// Here I use Newtonsoft.Json to deserialize JSON string to User object
var user = JsonConvert.DeserializeObject<User>(userString);
return user;
}
private static async Task<string> GetStringAsync(string url)
{
using (var httpClient = new HttpClient())
{
return await httpClient.GetStringAsync(url);
}
}
}
Here是哪裏/如何獲得Newtonsoft.Json
包。
另一種選擇是重用HttpClient
對象,使您的存儲庫IDisposable
因爲你需要處理HttpClient
,當你完成它的工作。在我的第一個示例中,它在using
聲明的末尾使用HttpClient
後立即發生。
啊我明白了!如果我還希望能夠通過電子郵件地址獲取用戶,我將添加'公共異步任務 GetUserAsync(字符串電子郵件){}',與整數id稍有不同。如果我還需要從同一個Web服務(用戶,角色,產品等)獲得其他類型的東西,該怎麼辦?將HttpClient的東西提取到某種類型的包裝類中是否有意義,並且讓存儲庫針對每個實體(UserRepository,RoleRepository,ProductRepository)是特定的? –
Jiveman
@Jiveman是的存儲庫,特定於實體是非常有意義的。如果您對所有存儲庫有共同之處,例如執行GET請求的泛型方法,則可以將其放入抽象的BaseRepository中。另外食物是單元測試庫。在這種情況下,你確實需要將你的HttpClient包裝成簡單的mockable類,並將它作爲依賴注入到repos中。 – Andrei
是的,單元測試絕對重要!謝謝你提到這一點。好的,這絕對有助於我以更好的方式思考事情。 – Jiveman