问题
I have a number of services which require usage of typed HttpClient from HttpClientFactory. Though I can resolve one service I can't resolve IEnumerable of this services.
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>>();
}
}
Constructor will be called once and than exception is thrown:
``` DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'ConsoleApp2.MyHttpClient' can be invoked with the available services and parameters: Cannot resolve parameter 'System.Net.Http.HttpClient client' of constructor 'Void .ctor(System.Net.Http.HttpClient)'.
```
The issue is that AddHttpClient adds it's own registration of IMyHttpClient. But I do want to register using Autofac only! Is there a way to use typed clients but still stay with Autofac?
回答1:
The exception explains that Autofac can't resolve parameter 'System.Net.Http.HttpClient client'. I suppose this is because such type wasn't registered in your container for second resgistration of IMyHttpClient
. To save an advantages of HttpClientFactory
you can register excplicit constructor parameter for example like this:
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>>();
}
In this example Resolve<IEnumerable<IMyHttpClient>>
return enumeration with single IMyHttpClient
, that is initialized with HttpClient
from core HttpClientFactory.
UPD: the post was updated by @norekhov comment
来源:https://stackoverflow.com/questions/52291150/autofac-fails-to-resolve-enumerable-of-typed-httpclients