Skip to main content
 首页 » 编程设计

c#之通过 StructureMap 定义 'HttpClient' 单例导致运行时未配置 'HttpMessageHandler' 的错误

2024年02月25日34lhb25

尝试在 StructureMap ala 中定义一个 HttpClient 单例:

For<HttpClient>().Singleton().UseIfNone<HttpClient>(); 

这会导致运行时出现以下错误(依赖注入(inject)时):

   StructureMap.StructureMapConfigurationException: No default Instance is registered and cannot be automatically determined for type 'System.Net.Http.HttpMessageHandler' 
 
   There is no configuration specified for System.Net.Http.HttpMessageHandler 
 
   1.) new HttpClient(*Default of HttpMessageHandler*) 
   2.) System.Net.Http.HttpClient 
   3.) Instance of System.Net.Http.HttpClient 
   4.) new AdmanAdapter(*Default of HttpClient*) 
   5.) Organotiki.vNext.PostEval.Data.Adapters.ADMAN.AdmanAdapter 
   6.) Instance of [....] 
 
      at lambda_method(Closure , IBuildSession , IContext ) 
      at StructureMap.Building.BuildPlan.Build(IBuildSession session, IContext context) 
      at StructureMap.BuildSession.BuildNewInSession(Type pluginType, Instance instance) 
      at StructureMap.Pipeline.NulloTransientCache.Get(Type pluginType, Instance instance, IBuildSession session) 
      at StructureMap.BuildSession.ResolveFromLifecycle(Type pluginType, Instance instance) 
      at StructureMap.SessionCache.GetObject(Type pluginType, Instance instance, ILifecycle lifecycle) 

如果我们也像这样配置 HttpMessageHandler:

For<HttpClient>().Singleton().UseIfNone<HttpClient>(); 
For<HttpMessageHandler>().UseIfNone(x => new HttpClientHandler()); 

然后问题就解决了。问题是为什么? HttpClient 的默认构造函数负责其自身的依赖注入(inject):

/// <summary>Initializes a new instance of the <see cref="T:System.Net.Http.HttpClient" /> class.</summary> 
[__DynamicallyInvokable] 
public HttpClient() 
  : this((HttpMessageHandler) new HttpClientHandler()) 
{ 
} 

我是不是漏掉了什么?

请您参考如下方法:

来自 http://structuremap.github.io/registration/constructor-selection 的结构图文档

If there are multiple public constructor functions on a concrete class, StructureMap's default behavior is to select the "greediest" constructor, i.e., the constructor function with the most parameters.

如果您查看HttpClient 的可能构造函数,它应该是

public HttpClient(); 
public HttpClient(HttpMessageHandler handler); 
public HttpClient(HttpMessageHandler handler, bool disposeHandler);