我已经使用存储库模式创建了我的数据提供程序。首先,我设计了一个基础存储库接口,如下所示:internal interface IGenericRepository<T, in TResourceIdentifier>{ Task<IEnumerable<T>> GetManyAsync(); Task<T> GetAsync(TResourceIdentifier id); Task PutAsync(T model); Task<T> PostAsync(T model); Task DeleteAsync(TResourceIdentifier id);}然后我实现了它:public class GenericRepository<T, TResourceIdentifier> : IDisposable, IGenericRepository<T, TResourceIdentifier> where T : class{ private bool _disposed; protected HttpClientHelper<T, TResourceIdentifier> Client; protected GenericRepository(string addressSuffix) { Client = new HttpClientHelper<T, TResourceIdentifier>(Properties.Settings.Url, addressSuffix); } public async Task<IEnumerable<T>> GetManyAsync() { return await Client.GetManyAsync(); } // All other CRUD methods and dispose public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if(_disposed || !disposing) return; if(Client != null) { var mc = Client; Client = null; mc.Dispose(); } _disposed = true; }}然后我为每个实体创建了自定义存储库接口。例如:internal interface IOrderRepository : IGenericRepository<Order, int>{ Task<IEnumerable<Order>> GetOrderBySomeConditionAsync(string condition );}最后,我实现了自定义存储库:public class OrderRepository : GenericRepository<Order, int>, IOrderRepository{ public OrderRepository(string addressSuffix) : base(addressSuffix) { } public async Task<IEnumerable<Order>> GetOrderBySomeConditionAsync(string condition) { //get all the orders (GetManyAsync()) and then returns the ones meeting the condition }}请注意,HttpClientHelper使用HttpClient,需要手动处置。我创建了一个 MVC Web 应用程序,并在类级别定义了存储库,如下所示:IOrderRepository _orderRepository = new OrderRepository();这会影响 Dispose,但却是反模式。我在实现中缺少什么,即每次调用时都没有释放该实例?
2 回答
慕莱坞森
TA贡献1810条经验 获得超4个赞
您不应该在每次请求后都处理 HTTPClient。
因此,HttpClient旨在实例化一次并重用 在应用程序的整个生命周期中。实例化 HttpClient 每个请求的类都会耗尽可用套接字的数量 在重负载下。该问题将导致 SocketException 错误。 解决该问题的可能方法基于创建 HttpClient 对象作为单例或静态,如此处所述 Microsoft 关于 HttpClient 使用的文章。
跃然一笑
TA贡献1826条经验 获得超6个赞
在通用存储库中编写 Dispose 方法并不意味着它会在您认为需要时自动调用。它旨在单独调用,因此您必须使用using
语句(就像您有所示),或代码中的 Dispose
方法。
或者,您可以将该工作留给垃圾收集器。
如果您确信使用,您还应该在通用存储库中创建一个终结器GC.SuppressFinalize(this);
您还应该创建一个静态类来保存 HttpClient。您必须使用 HttpResponseMessages 来满足您的需求,或者 HttpContent。
- 2 回答
- 0 关注
- 122 浏览
添加回答
举报
0/150
提交
取消