I have an IFunctionProvider implementation for an Azure Function that creates a route for /healthcheck. The entrypoint for my function metadata is a method called Somenamespace.TestTrigger.RenderHealthCheck. My code looks like this:
public class TestTrigger
{
public static async Task<IActionResult> RenderHealthCheck(HttpRequest req)
{
return new OkObjectResult("OK");
}
}
public class HealthCheckTrigger : IFunctionProvider
{
public ImmutableDictionary<string, ImmutableArray<string>> FunctionErrors { get; }
public async Task<ImmutableArray<FunctionMetadata>> GetFunctionMetadataAsync()
{
var assembly = Assembly.GetExecutingAssembly();
var functionMetadata = new FunctionMetadata()
{
Name = nameof(TestTrigger.RenderHealthCheck),
FunctionDirectory = null,
ScriptFile = $"assembly:{assembly.FullName}",
EntryPoint = $"{typeof(TestTrigger).FullName}.{nameof(TestTrigger.RenderHealthCheck)}",
Language = "DotNetAssembly"
};
var jo = JObject.FromObject(new HttpBindingMetadata()
{
Methods = new List<string> { HttpMethods.Get },
Route = "HealthCheck",
AuthLevel = AuthorizationLevel.Anonymous,
});
var binding = BindingMetadata.Create(jo);
functionMetadata.Bindings.Add(binding);
var functionMetadataList = new List<FunctionMetadata>
{
functionMetadata
};
return await Task.FromResult(functionMetadataList.ToImmutableArray()).ConfigureAwait(false);
}
}
This works fine, and when I run the function and hit the /HealthCheck endpoint I get my OK message. However, I'd like to make the RenderHealthCheck method non-static, so I can use dependency injection in the constructor and access various services in my application. I changed my code to:
public class TestTrigger
{
private readonly HealthCheckService healthCheckService;
public TestTrigger(HealthCheckService healthCheckService)
{
this.healthCheckService = healthCheckService;
}
public async Task<IActionResult> RenderHealthCheck(HttpRequest req)
{
return new OkObjectResult("OK");
}
}
Now, when I hit the endpoint, I get the following exception:
Executed 'Functions.RenderHealthCheck' (Failed, Id=c02a9ba6-1ed3-4c07-8b38-214d345b6ff1, Duration=488ms)
Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.RenderHealthCheck
---> System.NullReferenceException: Object reference not set to an instance of an object.
at lambda_method(Closure , TestTrigger , Object[] )
at Microsoft.Azure.WebJobs.Host.Executors.TaskMethodInvoker`2.InvokeAsync(TReflected instance, Object[] arguments) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\TaskMethodInvoker.cs:line 21
at Microsoft.Azure.WebJobs.Script.Description.DotNetFunctionInvoker.MethodInvoker`2.InvokeAsync(Object target, Object[] parameters) in D:\a\1\s\src\WebJobs.Script\Description\DotNet\DotNetFunctionInvoker.cs:line 533
at Microsoft.Azure.WebJobs.Script.Description.DotNetFunctionInvoker.InvokeCore(Object[] parameters, FunctionInvocationContext context) in D:\a\1\s\src\WebJobs.Script\Description\DotNet\DotNetFunctionInvoker.cs:line 272
at Microsoft.Azure.WebJobs.Script.Description.FunctionInvokerBase.Invoke(Object[] parameters) in D:\a\1\s\src\WebJobs.Script\Description\FunctionInvokerBase.cs:line 82
at Microsoft.Azure.WebJobs.Script.Description.FunctionGenerator.Coerce[T](Task`1 src) in D:\a\1\s\src\WebJobs.Script\Description\FunctionGenerator.cs:line 225
at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.InvokeAsync(Object instance, Object[] arguments) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 52
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeWithTimeoutAsync(IFunctionInvoker invoker, ParameterHelper parameterHelper, CancellationTokenSource timeoutTokenSource, CancellationTokenSource functionCancellationTokenSource, Boolean thro
wOnTimeout, TimeSpan timerInterval, IFunctionInstance instance) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 555
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\projects\azure-webjobs-sdk-r
qm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 503
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken
cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 281
--- End of inner exception stack trace --
I didn't see anything in the FunctionMetadata or HttpBindingMetadata that seems to control if the entrypoint is static. Are instance methods simply not supported? Seems like a huge limitation if not. There's basically zero documentation of any sort on IFunctionProvider so not quite sure where to go from here. Any help would be appreciated!