Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用HttpClient子类的类型化客户端_C#_Asp.net Core_Dependency Injection - Fatal编程技术网

C# 使用HttpClient子类的类型化客户端

C# 使用HttpClient子类的类型化客户端,c#,asp.net-core,dependency-injection,C#,Asp.net Core,Dependency Injection,在我的应用程序中,我几乎没有TypedClient服务。 但是,这些类将共享一组方法。 我的解决方案是创建CustomHttpClient: public class CustomHttpClient:HttpClient { //here shared methods } public class MyService : IMyService { public SomeService(CustomHttpClient client, IConfiguration configurat

在我的应用程序中,我几乎没有TypedClient服务。 但是,这些类将共享一组方法。 我的解决方案是创建CustomHttpClient:

public class CustomHttpClient:HttpClient
{
  //here shared methods
}
public class MyService : IMyService
{
  public SomeService(CustomHttpClient client, IConfiguration configuration){}
}
然后,我的类型化客户端类将使用此派生类而不是标准HttpClient:

public class CustomHttpClient:HttpClient
{
  //here shared methods
}
public class MyService : IMyService
{
  public SomeService(CustomHttpClient client, IConfiguration configuration){}
}
但是,如果我尝试在启动时注册此服务,我会收到一个错误,即“MyService”没有合适的构造函数:

services.AddHttpClient<IMyService, MyService>();
services.AddHttpClient();
在我找到的文档中:

这是否意味着它不能接受HttpClient的子类? 如果是这样的话,那么我唯一的解决方案就是将共享方法实现为HttpClient扩展方法(我真的不喜欢这个解决方案)。 是否有解决方法,或者扩展方法是我唯一的出路? 我也尝试注册CustomHttpClient,以便DI容器可以找到它,但错误仍然是一样的。 你能给我什么建议

这是否意味着它不能接受HttpClient的子类

如果是这种情况,那么我唯一的解决方案就是将共享方法实现为HttpClient扩展方法

否。根据类型,客户端封装了一个HttpClient,而不是扩展它。在构造函数中配置HttpClient,然后向使用封装HttpClient实例的类型化客户端添加自定义方法

如果您不想使用框架的模式来处理HttpClient,您可以自由创建自己的模式,但这可能不值得

您可以拥有共享基类的类型化客户端。乙二醇

public class MyBaseTypedClient
{
    public HttpClient Client { get; }

    public MyBaseTypedClient(HttpClient client)
    {
        client.BaseAddress = new Uri("https://api.github.com/");
        // GitHub API versioning
        client.DefaultRequestHeaders.Add("Accept",
            "application/vnd.github.v3+json");
        // GitHub requires a user-agent
        client.DefaultRequestHeaders.Add("User-Agent",
            "HttpClientFactory-Sample");

        Client = client;
    }

    //other methods

}
public class MyTypedClient : MyBaseTypedClient
{
    public MyTypedClient(HttpClient client) : base(client) { }
}

如果只需要添加公共方法,则可以使用这些方法的默认实现创建一个接口,然后只需要使用该接口继承IMyService

您还可以查看下面的链接,其中有一些有趣的解决方法


这正是我的问题。我有几个类型化的客户机,所以我必须在每个客户机中重复这些方法。所以我的选择是在每个类型化的客户机类中放置share方法,还是使用扩展方法?这就是您要说的?您可以让所有类型化客户端继承一个基类型,但它们都必须具有接受HttpClient的构造函数。请参阅更新的答案。键入的客户端不应该是客户端(is-a),而应该是自己的客户端(has-a)。它们都可以有一个共同的基础,但是与HttpClient的关系应该是所有权而不是继承。例如,HttpClientFactory对您的HttpClient子类一无所知,因此,如果需要,您必须完全重写该逻辑(由于您正在尝试使用http客户端注入,您可以隐式地重写该逻辑)而对于所有权模式,它所要做的就是将普通客户端注入到其他容器中;和服务。AddHttpClient();(其中MyService和MySecondService都继承自MyBaseTypedClient)创建为在MyService和MySecondService之间共享的httpClient的一个实例?或者每个都有各自独立的实例?独立的实例,但有一个共享的连接池。看,微软似乎更喜欢组合而不是继承,但是由于代码是开源的,您可能希望对其进行自定义。