猿问

如何使用 HttpClient 处理数据提供者实例?

我已经使用存储库模式创建了我的数据提供程序。


首先,我设计了一个基础存储库接口,如下所示:


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,但却是反模式。


我在实现中缺少什么,即每次调用时都没有释放该实例?


ITMISS
浏览 123回答 2
2回答

慕莱坞森

您不应该在每次请求后都处理 HTTPClient。因此,HttpClient旨在实例化一次并重用 在应用程序的整个生命周期中。实例化 HttpClient 每个请求的类都会耗尽可用套接字的数量 在重负载下。该问题将导致 SocketException 错误。 解决该问题的可能方法基于创建 HttpClient 对象作为单例或静态,如此处所述 Microsoft 关于 HttpClient 使用的文章。

跃然一笑

在通用存储库中编写 Dispose 方法并不意味着它会在您认为需要时自动调用。它旨在单独调用,因此您必须使用using语句(就像您有所示),或代码中的 Dispose 方法。或者,您可以将该工作留给垃圾收集器。如果您确信使用,您还应该在通用存储库中创建一个终结器GC.SuppressFinalize(this);您还应该创建一个静态类来保存 HttpClient。您必须使用 HttpResponseMessages 来满足您的需求,或者 HttpContent。
随时随地看视频慕课网APP
我要回答