Reputation: 165
I have an Azure Function running .Net 7 isolated, including the latest stable versions of:
I am following this dependency injection guide specific to isolated functions, and am having some trouble getting it working:
My Program.cs
contains this for injecting the dependency:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(s =>
{
s.AddSingleton<IMyInterface>(new MyConcreteClass(constructor args);
})
.Build();
await host.RunAsync();
And then in the Azure function code:
public class MyAzureFunction
{
[Function("MyAzureFunction")]
public async Task RunAsync([ATrigger(
...TheTriggerArgs...
)] IReadOnlyList<MyDataClass> input, IMyInterface myService)
{
myService.DoSomeWork(input); //exception is thrown here
}
}
There are no compiler warnings in VS, but a null reference exception is thrown when the function executes the commented line.
The error is:
System.NullReferenceException: Object reference not set to an instance of an object.
It seems the dependency injection is simply not working...
The exact same pattern and classes work fine for me in other apps like minimal API's and Blazor Apps, so I think this is something specific to Azure Functions?
If it makes any difference, I've also tried doing Azure Function dependency injection the "other" way (with a start method override) with the same result: https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection
Upvotes: 4
Views: 7168
Reputation: 165
I was able to solve this by adding the interface as a private property to the function class and creating a constructor which sets it using constructor injection.
I suppose that in web apps and other app templates it is doing this for you "in the background" - whereas in functions it does not.
program.cs is unchanged:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(s =>
{
s.AddSingleton<IMyInterface>(new MyConcreteClass(constructor args);
})
.Build();
await host.RunAsync();
Property and constructor added to the function class:
public class MyAzureFunction
{
private readonly IMyInterface _myInterface;
public MyAzureFunction(IMyInterface myInterface)
{
this._myInterface = myInterface;
}
[Function("MyAzureFunction")]
public async Task RunAsync([ATrigger(
...TheTriggerArgs...
)] IReadOnlyList<MyDataClass> input, IMyInterface myService)
{
myService.DoSomeWork(input);
}
}
This works correctly and solved the problem.
Upvotes: 6