Search code examples
c#dependency-injectionazure-functionsmicrosoft-extensions-di

How to make sure all C# Azure function triggers have valid dependency injection?


In our C# Azure functions app, we sometimes have issues where somebody adds a new dependency to a class used by a trigger, but forgets to add it to the DI container in Program.cs/Startup.cs. The application will still build and start, but an exception will be thrown when running the Azure function trigger.

How can we make sure that this type of error is caught at build time, when the application starts or in a test, rather than at runtime?


Solution

  • Here is a test that verifies that the trigger classes can be created, meaning that DI injection is setup correctly for all direct and indirect dependencies. In this case, we have an interface called IAzureTrigger which all trigger classes implement. This answer was used as a starting point.

    [Test]
    public void VerifyTriggerDependencyInjection()
    {
         using var host = new HostBuilder()
            .ConfigureFunctionsWorkerDefaults()
            .ConfigureServices(Program.ConfigureServices)
            .Build();
    
        var triggerTypes = typeof(IAzureTrigger).Assembly.ExportedTypes.Where(
            t => typeof(IAzureTrigger).IsAssignableFrom(t) && t.IsClass
        );
    
        var errors = new Dictionary<Type, Exception>();
        foreach (var triggerType in triggerTypes)
        {
            try
            {
                ActivatorUtilities.CreateInstance(host.Services, triggerType);
            }
            catch (Exception e)
            {
                errors.Add(triggerType, e);
            }
        }
    
        if (errors.Any())
        {
            Assert.Fail(
                string.Join(
                    $"{Environment.NewLine}{Environment.NewLine}",
                    errors.Select(
                        x =>
                            $"Failed to resolve trigger {x.Key.Name} due to {x.Value.Message}{Environment.NewLine}{x.Value.InnerException?.Message ?? ""}"
                    )
                )
            );
        }
    }