通过 StructureMap 定义 'HttpClient' 单例会导致有关 'HttpMessageHandler' 未在运行时配置的错误
Defining an 'HttpClient' singleton via StructureMap causes an error about 'HttpMessageHandler' being not configured in runtime
正在尝试在 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())
{
}
我是不是漏掉了什么?
来自 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);
扩展@Brad M 的回答,对我有用的是 .SelectConstructor(() => new HttpClient())
。明确指定应使用哪个构造函数。
正在尝试在 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())
{
}
我是不是漏掉了什么?
来自 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);
扩展@Brad M 的回答,对我有用的是 .SelectConstructor(() => new HttpClient())
。明确指定应使用哪个构造函数。