3

我们的MVC应用程序使用HttpClient调用WebAPI操作。我决定要注入的HttpClient使用StructureMap的并覆盖在处置控制器Dispose of Injected HttpClient

public HomeController(HttpClient httpClient) 
{ 
    _httpClient = httpClient; 
} 

protected override void Dispose(bool disposing) 
{ 
    if (disposing && _httpClient != null) 
    { 
     _httpClient.Dispose(); 
    } 
    base.Dispose(disposing); 
} 

的StructureMap ObjectInitialize基本上是这样的..

x.For<HttpClient>().Use(() => new HttpClient() { BaseAddress = "my/uri/"}); 

当我建立这个,CodeAnalysis抱怨"Dispose objects before losing scope"并指向的IoC码。

我可以抑制,或者我需要处置HttpClient?我也试过

protected void Application_EndRequest(object sender, EventArgs e) 
{ 
    ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects(); 
} 

但我仍然得到规则违规。

回答

5

处置HttpClient清理任何活动的取消令牌和任何部分完成的请求/响应。在大多数正常情况下,处置它并不重要,尽管按惯例你应该。请注意,处置HttpClient会强制关闭TCP连接。

如果您的MVC应用程序正在对同一台服务器进行大量调用,则可能值得在请求中保留HttpClient实例并重新使用它。这样可以避免每次都需要重新设置默认的请求标头,并且允许重新使用TCP连接。

3

触发对象创建的对象通常是负责处理对象的对象。在这种情况下,HttpClient由Structuremap通过DependencyResolverControllerFactory创建。使用Structuremap处理瞬态对象并不容易,所以您希望最大限度地减少对象的注入,尤其是瞬态对象。我认为你应该将创建和处理放在一个服务中,然后将其注入到控制器中。

ReleaseAndDisposeAllHttpScopedObjects在这种情况下将不起作用,因为它只处理配置为HttpScoped的对象,即在整个http请求期间保留的对象。

+0

这有帮助。感谢您的输入。如果我在StructureMap中使用“HttpContextScoped”,那么ReleaseAndDisposeAllHttpScopedObjects会起作用吗? – jlembke 2013-05-07 00:13:22

+1

@jlembke - 是的,使用'HttpContextScoped','ReleaseAndDisposeAllHttpScopedObjects'方法可以工作。 – PHeiberg 2013-05-07 10:52:31