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

问题描述 投票:1回答:2

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

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

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

   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的默认构造函数负责自己的依赖注入:

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

我在这里错过了什么吗?

c# rest dependency-injection structuremap dotnet-httpclient
2个回答
2
投票

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

如果在具体类上有多个公共构造函数,StructureMap的默认行为是选择“最贪婪”的构造函数,即具有最多参数的构造函数。

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

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

1
投票

扩展@Brad M的答案,对我有用的是.SelectConstructor(() => new HttpClient())。指定应明确使用哪个构造函数。

© www.soinside.com 2019 - 2024. All rights reserved.