Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency Injection unable to resolve service for type in .NET Core Function App running in Azure

Summary

I've been following the Microsoft guidance Use dependency injection in .NET Azure Functions to introduce some Dependency Injection (DI) into an Azure Function that our team is creating. When I run locally in Visual Studio 2017 and invoke the function using Fiddler or Postman everything works - I can debug hitting breakpoints and the service being provided via the DI setup are working correctly. When we deploy the same function into Azure, however, we get the following exception:

Unable to resolve service for type 'MyLibrary.ITelemetryClient' while attempting to activate 'MyFunctionApp.GetRemoteSystemsByFeature'.

Details

I have a library assembly (.NET Standard 2.0) that exposes an interface, ITelemetryClient, and a default implementation, ApplicationInsightsTelemetryClient. They're pretty straightforward bits of code - I don't think the implementation of these are important to the issue, so I'll skip them for now.

In the solution that defines our function app (.NET Core 2.2) I've made sure the right NuGet packages are installed:

  • Microsoft.Azure.Functions.Extensions v1.0.0
  • Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator v1.1.1
  • Microsoft.NET.Sdk.Functions v1.0.28

I have created Startup which inherits from FunctionsStartup:

using System;
using System.Runtime.CompilerServices;
using MyLibrary;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(MyFunctionApp.Startup))]
[assembly: InternalsVisibleTo("MyFunctionApp.Tests")]

namespace MyFunctionApp
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddSingleton<MyLibrary.ITelemetryClient, MyLibrary.ApplicationInsightsTelemetryClient>();
        }
    }
}

I then give my function a constructor that asks for the MyLibrary.ITelemetryClient:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
using MyLibrary;
using MyRepository;
using MyService;

namespace MyFunctionApp
{
    public class GetRemoteSystemsByFeature
    {
        private readonly MyLibrary.ITelemetryClient _telemetryClient;

        public GetRemoteSystemsByFeature(MyLibrary.ITelemetryClient telemetryClient)
        {
            _telemetryClient = telemetryClient;
        }

        // snip - the rest shouldn't matter for this question
    }
}

So I think I've done everything right. And as I said when I debug locally the whole thing works and the correct ITelemetryClient implementation is used and successfully does its thing.

When it gets deployed into Azure, though, we get the error quoted above. The stack trace for that exception doesn't mention any of our code:

System.InvalidOperationException:
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService (Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at lambda_method (Anonymously Hosted DynamicMethods Assembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)
   at Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstance (Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\DefaultJobActivator.csMicrosoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: 42)
   at Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstance (Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\DefaultJobActivator.csMicrosoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: 32)
   at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory`1+<>c__DisplayClass1_1.<.ctor>b__0 (Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\ActivatorInstanceFactory.csMicrosoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: 20)
   at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory`1.Create (Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\ActivatorInstanceFactory.csMicrosoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: 26)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.CreateInstance (Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.csMicrosoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: 44)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor+ParameterHelper.Initialize (Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.csMicrosoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: 845)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor+<TryExecuteAsyncCore>d__16.MoveNext (Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35Microsoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.csMicrosoft.Azure.WebJobs.Host, Version=3.0.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: 116)

Any ideas?

Update

It was requested I share the contents of the extensions.json file:

{
  "extensions":[
    { "name": "Startup", "typeName":"MyFunctionApp.Startup, MyFunctionApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"}
  ]
}
like image 790
BigPigVT Avatar asked Oct 26 '25 18:10

BigPigVT


2 Answers

In my case I was missing [assembly: FunctionsStartup(typeof(MyFunctionApp.Startup))]

like image 117
Kaido Avatar answered Oct 28 '25 10:10

Kaido


After uninstalling the Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator package from the MyFunctionApp and redeploying the dependency injection errors stopped and things started working correctly. Thanks to anyone who offered their insights, especially to Katy Shimizu.

like image 23
BigPigVT Avatar answered Oct 28 '25 08:10

BigPigVT