0

I am having a problem where I have multiple azure functions deployed on a single app service and I am getting dependency injection errors.

  • Azure Function V2 runtime
  • Doesn't error when there is only one function enabled
  • Restarting the app doesn't help but If I redeploy the same binaries, the error will go away for the first run then return for subsequent runs
  • Other functions will exhibit the same error but for different services
  • I tried remote debugging but I can't get it to hit any breakpoints or trigger the exception view
  • Works fine locally

This is the exception from the Azure Function portal view:

2020-02-19T06:34:33.432 [Error] Executed 'Logger' (Failed, Id=edfbcc63-09b6-4f9e-8ee3-81fe50fd9412)
System.InvalidOperationException : Unable to resolve service for type 'Cloud.Services.Storage.Azure.IAzureTableStorageService' while attempting to activate 'Cloud.Web.AzureFunctions.Functions.Logger.Logger'.
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp,Type type,Type requiredBy,Boolean isDefaultParameterRequired)
   at lambda_method(Closure ,IServiceProvider ,Object[] )
   at Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstance[T](IServiceProvider serviceProvider) at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\DefaultJobActivator.cs : 37
   at Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstance[T](IFunctionInstanceEx functionInstance) at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\DefaultJobActivator.cs : 32
   at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory`1.<>c__DisplayClass1_1.<.ctor>b__0(IFunctionInstanceEx i) at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\ActivatorInstanceFactory.cs : 20
   at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory`1.Create(IFunctionInstanceEx functionInstance) at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\ActivatorInstanceFactory.cs : 26
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.CreateInstance(IFunctionInstanceEx functionInstance) at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs : 44
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ParameterHelper.Initialize() at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs : 846
   at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsyncCore(IFunctionInstanceEx functionInstance,CancellationToken cancellationToken) at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs : 116

Code:

Function Definition:

[assembly: WebJobsStartup(typeof(FunctionStartUp))]
namespace Cloud.Web.AzureFunctions.Functions.Logger
{
    public class Logger
    {
        private readonly IAzureTableStorageService _azureTableStorageService;
        public Logger(IAzureTableStorageService azureTableStorageService)
        {
            _azureTableStorageService = azureTableStorageService;
        }

        [FunctionName("Logger")]
        public async Task Run(
            [ServiceBusTrigger("logger", Connection = @"ServiceBusConnectionString")]
            EntityLogEntry myQueueItem,
            ILogger log,
            ExecutionContext context)
        {...}

Startup:

public class FunctionStartUp : IWebJobsStartup
{
    public static ServiceProvider Container { get; private set; }

    public void Configure(IWebJobsBuilder builder)
    {
        Container = CoreAppModule.ConfigureServices(builder.Services).BuildServiceProvider();
    }
}
public class CoreAppModule
    {
        public static IServiceCollection ConfigureServices(IServiceCollection services)
        {
            var config = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("local.settings.json", true) //when deployed, all application settings must be stored in azure app configuration
                .AddEnvironmentVariables()
                .Build();

            services.SetupConnectionStrings(config);
            services.AddOptions();
            services.SetupAutoMapper();
            services.SetupMongoRepositories(config);
            services.SetupDbContextsEFCore();
            services.SetupDataServices(config);
            services.SetupServices(config);
            services.SetupInMemoryCache();
            services.SetupIntegrationServices(config);
            services.SetupStorageServices(config);
            services.SetupCrypto(config);
            services.SetupIntegrationLibraryServices(config);
            services.SetupFtpConnectionDetails(config);
            services.SetupServiceBus(config);
            services.SetupStartupInitialization(config);

            return services;
        }
    }

Dependencies:

enter image description here

Portal Settings:

enter image description here enter image description here

7
  • Please post the your Startup class the register with your DI Commented Feb 18, 2020 at 17:16
  • @JSteward Updated. Commented Feb 19, 2020 at 6:42
  • @josh Since you only encountered this problem when running on Azure, what is your host.json on Azure? Go to Function AppSettings Dialog to see if there is an extensionBundle in the host.json file, if so, delete it and save. Commented Feb 19, 2020 at 10:16
  • @BowmanZhu host.json is essentially empty, just {} Commented Feb 19, 2020 at 14:30
  • @josh I am facing the same isse. Did you find the solution for this? Commented Jun 27, 2020 at 5:46

2 Answers 2

1

There is file called extensions.json in the bin folder. Your startup calls register in that file. Whichever function app deployed latest, that function's startup call will be replaced with earlier function's startup call. So, you need to take an action that all the functions' startup calls will be registered in this file.

enter image description here

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

0

Seems like you haven't injected IAzureTableStorageService properly in your Startup class hence the DI can't find it. Reference the project where IAzureTableStorageService is located, add something like this in your Startup class:

services.AddTransient<IAzureTableStorageService, AzureTableStorageService>();

where AzureTableStorageService is your class that implements IAzureTableStorageService.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.