Constructor dependency injection for web jobs causes an error in 3.0.0-rc1
See original GitHub issueRepro steps
- Add interface to be injected into the functions.
- Add interface to the functions constructor.
- Run the web job.
Expected behavior
Programme to run with the injected interface working.
Actual behavior
Webjob errors with “Object reference not set to an instance of an object”
Related information
Provide any related information Error
fail: Host.Results[0] Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ProcessWorkItem_ServiceBus —> System.NullReferenceException: Object reference not set to an instance of an object. at lambda_method(Closure , Functions , Object[] ) at Microsoft.Azure.WebJobs.Host.Executors.VoidTaskMethodInvoker 2.InvokeAsync(TReflected instance, Object[] arguments) in azure-webjobs-sdk-3.0.0-rc1\azure-webjobs-sdk-3.0.0-rc1\src\Microsoft.Azure.WebJobs.Host\Executors\VoidTaskMethodInvoker.cs:line 20 at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker 2.InvokeAsync(Object instance, Object[] arguments) in azure-webjobs-sdk-3.0.0-rc1\azure-webjobs-sdk-3.0.0-rc1\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 63 at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeAsync(IFunctionInvoker invoker, ParameterHelper parameterHelper, CancellationTokenSource timeoutTokenSource, CancellationTokenSource functionCancellationTokenSource, Boolean throwOnTimeout, TimeSpan timerInterval, IFunctionInstance instance) in azure-webjobs-sdk-3.0.0-rc1\azure-webjobs-sdk-3.0.0-rc1\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 562 at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstance instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in azure-webjobs-sdk-3.0.0-rc1\azure-webjobs-sdk-3.0.0-rc1\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 509 at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstance instance, ParameterHelper parameterHelper, IFunctionOutputDefinition outputDefinition, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in azure-webjobs-sdk-3.0.0-rc1\azure-webjobs-sdk-3.0.0-rc1\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 445 at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstance instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in azure-webjobs-sdk-3.0.0-rc1\azure-webjobs-sdk-3.0.0-rc1\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 249 — End of inner exception stack trace — at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstance instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in azure-webjobs-sdk-3.0.0-rc1\azure-webjobs-sdk-3.0.0-rc1\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 293 at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsync(IFunctionInstance functionInstance, CancellationToken cancellationToken) in azure-webjobs-sdk-3.0.0-rc1\azure-webjobs-sdk-3.0.0-rc1\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 89
Program.cs
public static async Task Main(string[] args)
{
var builder = new HostBuilder()
.UseEnvironment("Development")
.ConfigureWebJobs(b =>
{
b.AddDashboardLogging()
.AddAzureStorageCoreServices()
.AddAzureStorage()
.AddServiceBus()
.AddEventHubs()
.AddExecutionContextBinding();
})
.ConfigureAppConfiguration(b =>
{
// Adding command line as a configuration source
b.AddCommandLine(args);
})
.ConfigureServices((hostContext, services) => {
services.AddSingleton<IJobActivator>(new JobActivator(services.BuildServiceProvider()));
services.AddScoped<Functions, Functions>();
services.AddSingleton<IWriteText, WriteText>(); })
.ConfigureLogging((context, b) =>
{
b.SetMinimumLevel(LogLevel.Debug);
b.AddConsole();
// If this key exists in any config, use it to enable App Insights
string appInsightsKey = context.Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"];
if (!string.IsNullOrEmpty(appInsightsKey))
{
b.AddApplicationInsights(o => o.InstrumentationKey = appInsightsKey);
}
})
.UseConsoleLifetime();
var host = builder.Build();
using (host)
{
await host.RunAsync();
}
}
Functions.cs
public class Functions
{
private readonly IWriteText _writeText;
public Functions(IWriteText writeText)
{
_writeText = writeText;
}
public async Task ProcessWorkItem_ServiceBus(
[ServiceBusTrigger("%queue%", Connection = "AzureWebJobsServiceBus")] string item, ILogger log)
{
log.LogInformation(_writeText.PopPop());
}
}
IWriteText.cs
public interface IWriteText
{
string PopPop();
}
public class WriteText : IWriteText
{
public string PopPop()
{
return "Pop Pop!";
}
}
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:10 (3 by maintainers)
Top GitHub Comments
Amy news on first class DI support, and documentation?
Hi @mathewc, @fabiocav’s change does indeed fix the problem. Wonder how I missed that. When implementing an
IJobActicatorEx
, the suppliedIFunctionInstanceEx
contains aIServiceProvider
property, which is the actual scoped provider. This means that every DI Container should now be able to plugin to this model. Here’s the Simple Injector verion:By using the following configuration, jobs can be resolved using Simple Injector:
Awesome work @fabiocav.