Search code examples
c#azure-functionsazure-functions-core-tools

Resolving service for IHttpClientFactory fails on Azure Function


I am trying to inject IHttpClientFactory service on Azure Function v3, but I keep getting the following erorr saying resolving a service failed. I use azure-functions-core-tools@v3 to run Azure Function locally.

[2/14/2020 5:45:19 PM] Executed 'Foo' (Failed, Id=24489b3b-af99-417e-b175-443b76c241d5)
[2/14/2020 5:45:19 PM] Microsoft.Extensions.DependencyInjection.Abstractions: Unable to resolve service for type 'System.Net.Http.IHttpClientFactory' while attempting to activate 'MyFunction.Function.Foo'.

I have a startup class that is supposed to inject a service for IHttpClientFactory.

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;

namespace MyFunction
{
    public class Startup : FunctionsStartup
    {

        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddHttpClient();
        }
    }
}

And below is an azure function class that uses injected service of IHttpClientFactory to create a HTTP client and send a GET request to a server.

using System.Threading.Tasks;
using System.Net.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

namespace MyFunction.Function
{
    public class Foo
    {
        private readonly HttpClient httpClient;
        public Scrape(IHttpClientFactory httpClientFactory)
        {
            httpClient = httpClientFactory.CreateClient();
        }

        [FunctionName("Foo")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            var result = await httpClient.GetAsync("https://google.com");
            var data = await result.Content.ReadAsStringAsync();
            return new OkObjectResult(data);
        }
    }
}

Am I missing something?


Solution

  • It looks like your startup.cs class is missing it's assembly reference?

    [assembly: FunctionsStartup(typeof(MyFunction.Startup))]
    

    Try adding that to the startup class. Add it just after your using statements at the top, and before any namespace declaration.

    Also, most examples I have seen show the client actually created during function execution, not in the default constructor.

    using System.Threading.Tasks;
    using System.Net.Http;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.Http;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Logging;
    
    namespace MyFunction.Function
    {
        public class Foo
        {
            private readonly HttpClient httpClient;
            public Scrape(IHttpClientFactory httpClientFactory)
            {
                factory = httpClientFactory;
            }
    
            [FunctionName("Foo")]
            public async Task<IActionResult> Run(
                [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
                ILogger log)
            {
                HttpClient httpClient = factory.CreateClient();
                var result = await httpClient.GetAsync("https://google.com");
                var data = await result.Content.ReadAsStringAsync();
                return new OkObjectResult(data);
            }
        }
    }