简体   繁体   English

使用Castle-Windsor在MVC4中使用HttpClient的方式

[英]Lifestyle of a HttpClient in MVC4 using castle-windsor

In a web-request I want to do a call to another server using Microsoft HttpClient. 在Web请求中,我想使用Microsoft HttpClient调用另一个服务器。 I am using MVC4 (hosted in IIS), and castle-windsor as IOC-container. 我正在使用MVC4(托管在IIS中),并将Castle-windsor用作IOC容器。 I read that the HttpClient is designed to live during serveral calls, and my question is how I should implement this. 我读到HttpClient旨在在服务器调用期间使用,我的问题是我应该如何实现这一点。

I come up with a few options: 我提出一些选择:

  1. Ignore the fact that HttpClient is designed for multiple calls, and create a new one each time i need one. 忽略HttpClient专为多个调用而设计的事实,并在每次需要时创建一个新的调用。
  2. Create a Singleton(lifestyle in castle) object which stores the HttpClient between calls. 创建一个Singleton(城堡中的生活方式)对象,该对象存储两次调用之间的HttpClient。 Are there any risks with this? 这有什么风险吗? Will the performace be bad, if multiple web-request is using the same HTTP-client? 如果多个Web请求使用同一个HTTP客户端,则性能会不好吗?

Are there any better pattern to do this? 有没有更好的方法可以做到这一点?

I would use LifestyleTransient to create a new one for each request. 我将使用LifestyleTransient为每个请求创建一个新请求。 That's safest when you're not sure that the class can function as a singleton. 当您不确定类是否可以作为单例函数使用时,这是最安全的。

It's also not a bad idea to depend on an abstraction (an interface) rather than on the HttpClient directly unless you're certain that the class would never be used apart from making HTTP requests. 依赖于抽象(接口)而不是直接依赖于HttpClient也不是一个坏主意,除非您确定该类除了发出HTTP请求外不会被使用。 Even then it may make unit testing easier. 即使那样,它也可以使单元测试更加容易。 That's one of the big benefits of using Windsor or another DI container. 这是使用Windsor或另一个DI容器的最大好处之一。 Otherwise there's not much benefit over just instantiating an HttpClient directly in your class. 否则,仅在您的类中直接实例化HttpClient并没有太多好处。


Update. 更新。 I did some looking and found this answer indicating that an HttpClient should be reused for a given API. 我做了一些查找,发现了这个答案,表明应该为给定的API重用HttpClient It's highly upvoted and I don't see any dissent from experience (or otherwise) so I'm going to reference it when doing some near-term development. 它被高度评价,我从经验(或其他方面)看不到任何异议,因此在进行一些近期开发时将参考它。

I would implement this by defining a strongly-typed client class that implements an interface, and then depending on the interface in my classes (not directly on the client.) Then Windsor can create the class for an interface and maintain it as a singleton. 我将通过定义一个实现接口的强类型客户端类,然后根据我的类中的接口(而不是直接在客户端上)来实现此目的。然后,Windsor可以为接口创建类并将其保持为单例。

By default if you create a new instance of HttpClient for each call, then each call will create a new TCP connection, and this will cause latency and reduced throughput. 默认情况下,如果为每个调用创建一个新的HttpClient实例,则每个调用将创建一个新的TCP连接,这将导致延迟和吞吐量降低。 If you want to have a new HttpClient instance because it's got per-call data on it, then you can have a singleton HttpClientHandler, pass it to the HttpClient ctor, and that will share the TCP connections across the HttpClient instances. 如果您想要一个新的HttpClient实例,因为它上面有按调用的数据,那么您可以拥有一个单例HttpClientHandler,将其传递给HttpClient ctor,它将在整个HttpClient实例之间共享TCP连接。

Scott, here are three approaches we have used that work. 斯科特,这是我们使用的三种方法。 I hope this helps, I'm new to stackoverflow so can't post more than two links apparently. 我希望这会有所帮助,我是Stackoverflow的新手,所以显然不能发布两个以上的链接。

1) Just have a static/singleton HttpClient, and pass any per-call headers with HttpRequestMessage as described here 1)只需拥有一个静态/单个HttpClient,并按此处所述通过HttpRequestMessage传递所有按调用标头

2) Have a static/singleton WebRequest|HttpClientHandler, and pass that to the HttpClient ctor with disposeHandler set to false. 2)拥有一个静态/单个WebRequest | HttpClientHandler,并将其传递给HttpClient ctor,并将disposeHandler设置为false。

3) In some cases, we had a DelegatingHandler instrumentation library that needed to be disposed after each HttpClient call. 3)在某些情况下,我们有一个DelegatingHandler工具库,需要在每个HttpClient调用之后进行处置。 So we created a WebRequestHandler that does nothing in Dispose() as below, passed that to the DelegatingHandler ctor, and then passed the DelegatingHandler to the HttpClient ctor with disposeHandler set to false. 因此,如下所示,我们创建了一个在Dispose()中不执行任何操作的WebRequestHandler,将其传递给DelegatingHandler ctor,然后将DislegatingHandler传递给HttpClient ctor,并将disposeHandler设置为false。

public class LongLivedWebRequestHandler : WebRequestHandler
{
    public override void Dispose()
    {
        // Do nothing...
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM