gpt4 book ai didi

c# - 在类库项目的基类中定义 HttpClient 实例的最佳方法是什么?

转载 作者:太空宇宙 更新时间:2023-11-03 14:40:13 25 4
gpt4 key购买 nike

有一个应用程序有 3 个接口(interface),任何想要使用这个应用程序的人都需要实现这些接口(interface)。我创建了一个类库项目,其中包含我从同一个基类继承的所有接口(interface)实现,以便能够拥有一个 HttpClient。这是我到目前为止所做的:

    public class BaseProxy
{
protected static readonly HttpClient Client;

static BaseProxy()
{
Client = new HttpClient();
}
}

并且我已经在所有派生类中使用此客户端来发出 GetAsync 和 PostAsync 请求,如下所示:

    public class XProxyImplementation
{
var response = Client.GetAsync(BaseUrl + "XXXApi/GetClientSettings/").Result;
response.EnsureSuccessStatusCode();
}

Web API 中的方法都不是异步的,我选择单例解决方案是因为我不想对每个请求都使用 using block 。我的问题是我应该寻求 DI 解决方案,还是这段代码足以用于将在内部使用的应用程序?欢迎提出所有改进建议。

我已经阅读了很多关于使用 DI 容器的答案,但这只是一个带有代理实现的类库。

我的另一个问题是,即使我想使用 DI,目前我也无法在我的构造函数类中引入 DI,因为使用我的实现的其他应用程序正在寻找一个空的构造函数。当我尝试将 HttpClient 参数传递给构造函数时,出现以下错误:

The current type, System.Net.Http.HttpMessageHandler, is an abstract class and cannot be constructed

使用我的 dll 的应用程序不允许我将任何参数传递给使用任何抽象类的构造函数。我猜这个应用程序使用 Unity 进行握手,并以某种方式寻找一个空的构造函数。一旦我尝试进行以下更改,我就会收到错误消息:

        public BaseProxy() : this(Service.HttpClient)
{
}

public XProxyImplementation(HttpClient client) : base(client)
{
}

这就是为什么我实际上更喜欢单例实例而不是 DI 实现。

最佳答案

迪?是的

DI 将启用代理类的可测试性,而您当前的实现无法进行单元测试。它还将改进关注点分离:remove the responsibility控制 HttpClient代理的生命周期。

通常,你会做这样的事情:

public abstract class BaseProxy
{
protected readonly HttpClient Client;

protected BaseProxy(HttpClient client)
{
Client = client;
}

// ... other members
}

public class XProxyImplementation : BaseProxy
{
public XProxyImplementation(HttpClient client) : base(client)
{
}

// ... other members

public Task SendRequest() // for example
{
return Client.GetAsync("....");
}
}

在测试期间,您将初始化 HttpClient 的不同实例, 注入(inject) HttpMessageHandler 的测试友好实现:

// you implement TestHttpMessageHandler that aids your tests
var httpClient = new HttpClient(new TestHttpMessageHandler());
var proxyUnderTest = new XProxyImplementation(httpClient);

参见 this blog post用于解释使用 HttpClientHttpMessageHandler 进行单元测试。

DI容器?否

既然我们在您的代码中引入了依赖注入(inject),下一个问题是,应该使用什么注入(inject)机制。

在您的具体情况下,我会投票反对耦合到任何特定的 DI 容器,因为您希望您的库被许多不同的应用程序使用,并且您不想膨胀它们的依赖项(应用程序可能已经在使用不同的 DI 容器)。

此外,由于您发布的代码非常简单,所以成熟的 DI 容器未免太过分了。在生产代码中,您可以将单例 HttpClient 移动到“服务定位器”:

public static class SingletonServices
{
public static readonly HttpClient HttpClient;

static SingletonServices()
{
HttpClient = new HttpClient();
}
}

因此,当您在生产代码中实例化代理时,您可以这样做:

var proxy = new XProxyImplementation(SingletonServices.HttpClient);

关于c# - 在类库项目的基类中定义 HttpClient 实例的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57290773/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com