Autofac 无法解析可枚举类型的 HttpClient
Autofac fails to resolve enumerable of typed HttpClients
我有许多服务需要使用来自 HttpClientFactory 的类型化 HttpClient。
虽然我可以解析一项服务,但我无法解析此服务的 IEnumerable。
interface IMyHttpClient
{
}
class MyHttpClient: IMyHttpClient
{
public MyHttpClient(HttpClient client)
{
}
}
class Program
{
static void Main(string[] args)
{
var services = new ServiceCollection();
services.AddHttpClient()
.AddHttpClient<IMyHttpClient, MyHttpClient>();
var builder = new ContainerBuilder();
// Exception goes away when remove this line
builder.RegisterType<MyHttpClient>().As<IMyHttpClient>();
builder.Populate(services);
var provider = builder.Build();
// ============== This works
// provider.Resolve<IMyHttpClient>();
// ============== This throws exception
provider.Resolve<IEnumerable<IMyHttpClient>>();
}
}
构造函数将被调用一次然后抛出异常:
```
DependencyResolutionException:可以使用可用的服务和参数调用类型 'ConsoleApp2.MyHttpClient' 上使用 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' 找到的构造函数的 None:
无法解析构造函数 'Void .ctor(System.Net.Http.HttpClient)' 的参数 'System.Net.Http.HttpClient client'。
```
问题是 AddHttpClient 添加了它自己的 IMyHttpClient 注册。但我确实只想使用 Autofac 进行注册!有没有一种方法可以使用类型化的客户端,但仍然使用 Autofac?
异常说明 Autofac 无法解析参数 'System.Net.Http.HttpClient client'。我想这是因为这种类型没有在您的容器中注册 IMyHttpClient
的第二次注册。为了保留 HttpClientFactory
的优势,您可以像这样注册显式构造函数参数:
static void Main(string[] args)
{
var services = new ServiceCollection();
services.AddHttpClient();
var builder = new ContainerBuilder();
// exclicit resolving client for constructor
builder.RegisterType<MyHttpClient>().As<IMyHttpClient>().WithParameter(
(p, ctx) => p.ParameterType == typeof(HttpClient),
(p, ctx) => ctx.Resolve<IHttpClientFactory>().CreateClient());
builder.Populate(services);
var provider = builder.Build();
// ============== This works
provider.Resolve<IMyHttpClient>();
// ============== This works too
provider.Resolve<IEnumerable<IMyHttpClient>>();
}
在此示例中,Resolve<IEnumerable<IMyHttpClient>>
return 具有单个 IMyHttpClient
的枚举,使用来自核心 HttpClientFactory 的 HttpClient
初始化。
更新:post 由@norekhov 评论更新
我有许多服务需要使用来自 HttpClientFactory 的类型化 HttpClient。 虽然我可以解析一项服务,但我无法解析此服务的 IEnumerable。
interface IMyHttpClient
{
}
class MyHttpClient: IMyHttpClient
{
public MyHttpClient(HttpClient client)
{
}
}
class Program
{
static void Main(string[] args)
{
var services = new ServiceCollection();
services.AddHttpClient()
.AddHttpClient<IMyHttpClient, MyHttpClient>();
var builder = new ContainerBuilder();
// Exception goes away when remove this line
builder.RegisterType<MyHttpClient>().As<IMyHttpClient>();
builder.Populate(services);
var provider = builder.Build();
// ============== This works
// provider.Resolve<IMyHttpClient>();
// ============== This throws exception
provider.Resolve<IEnumerable<IMyHttpClient>>();
}
}
构造函数将被调用一次然后抛出异常:
``` DependencyResolutionException:可以使用可用的服务和参数调用类型 'ConsoleApp2.MyHttpClient' 上使用 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' 找到的构造函数的 None: 无法解析构造函数 'Void .ctor(System.Net.Http.HttpClient)' 的参数 'System.Net.Http.HttpClient client'。
```
问题是 AddHttpClient 添加了它自己的 IMyHttpClient 注册。但我确实只想使用 Autofac 进行注册!有没有一种方法可以使用类型化的客户端,但仍然使用 Autofac?
异常说明 Autofac 无法解析参数 'System.Net.Http.HttpClient client'。我想这是因为这种类型没有在您的容器中注册 IMyHttpClient
的第二次注册。为了保留 HttpClientFactory
的优势,您可以像这样注册显式构造函数参数:
static void Main(string[] args)
{
var services = new ServiceCollection();
services.AddHttpClient();
var builder = new ContainerBuilder();
// exclicit resolving client for constructor
builder.RegisterType<MyHttpClient>().As<IMyHttpClient>().WithParameter(
(p, ctx) => p.ParameterType == typeof(HttpClient),
(p, ctx) => ctx.Resolve<IHttpClientFactory>().CreateClient());
builder.Populate(services);
var provider = builder.Build();
// ============== This works
provider.Resolve<IMyHttpClient>();
// ============== This works too
provider.Resolve<IEnumerable<IMyHttpClient>>();
}
在此示例中,Resolve<IEnumerable<IMyHttpClient>>
return 具有单个 IMyHttpClient
的枚举,使用来自核心 HttpClientFactory 的 HttpClient
初始化。
更新:post 由@norekhov 评论更新