Search code examples
c#dependency-injectionazure-functionssimple-injector

IHttpClientFactory and SimpleInjector in AzureFunctions


In Azure Functions (v3 on NetCore3.1) using SimpleInjector 5.3, I've followed the guidance here using IHttpClientFactory instead of a typed client that depends on a MS DI-constructed HttpClient, but SimpleInjector can't resolve the IHttpClientFactory either.

public class FooClient
{
    private IHttpClientFactory _clientFactory;
    private FooClientConfig _config;        
    public FooClient(IHttpClientFactory clientFactory, FooClientConfig config) 
    {
        _clientFactory = clientFactory;
        _config = config;           
    }
}
public class Startup : FunctionsStartup
{  
    public void ConfigureServices(IServiceCollection services)
    {   
        services.AddHttpClient();
    
        var container = new Container();
        container.RegisterInstance<FooClientConfig>(new FooClientConfig() { ApiKey = Configuration.GetValue<string>("FooApiKey") });
        container.Register<FooClient>();

        services.AddSimpleInjector(container);
    }
}
public class FooCommandHandler 
{
    private readonly FooClient _fooClient;
    
    public FooCommandHandler (FooClient client) 
    {
      _fooClient = fooClient;
    }
}

I then use the container to activate a Command/Query mediator but the container can't find an IHttpClientFactory to use for the FooClient.

SimpleInjector.ActivationException: 'The configuration is invalid. Creating the instance for type FooClient failed. The constructor of type FooClient contains the parameter with name 'clientFactory' and type IHttpClientFactory, but IHttpClientFactory is not registered. For IHttpClientFactory to be resolved, it must be registered in the container. Verification was triggered because Container.Options.EnableAutoVerification was enabled. To prevent the container from being verified on first resolve, set Container.Options.EnableAutoVerification to false.'

I guess my question is, where am I supposed to setup the Auto-cross-wiring for simpleinjector? I thought the call to services.AddSimpleInjector(container); would make the MS DI registered IHttpClientFactory available to the container and thus to the registrations therein.


Solution

  • Following the integration guide that Steven has put together over at the SimpleInjector docs VERY CAREFULLY, and using IHttpClientFactory instead of any typed clients I was finally able to get this to work - it is not pretty though.

    I suggest that if you're using anything other than the Http factory pattern in the old Azure Functions ecosystem (non-isolated) you'll be fine. It's the cross-wiring of certain services like HttpClient under the hood that makes this a total mess. Hope this helps anyone else facing the same issue.