Reputation: 1319
Microsoft DI for Azure Functions using 3.0 works quite surprisingly.
It injects null if service is not located instead of throwing an exception. It happens only for sub-dependencies (not root), in below case, if any parameter of OutboxRelay
constructor is missing, DI resolves it as null instead of throwing an exception that service is not registered.
I have a following Azure Function 3.0 :
public class OutboxRelayFunction
{
private readonly IOutboxRelay _outboxRelay;
public OutboxRelayFunction(IOutboxRelay outboxRelay)
{
_outboxRelay = outboxRelay;
}
[FunctionName("OutboxRelay")]
public async Task Run([TimerTrigger("*/1 * * * * *")]TimerInfo myTimer, ILogger log)
{
}
}
I've configured DI using Microsoft's container:
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(Startup))]
namespace Outbox.Relay
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddScoped<IOutboxRelay, OutboxRelay>();
builder.Services.AddSingleton<IBusClient, ServiceBusClient>();
}
}
}
OutboxRelay constructor:
public class OutboxRelay : IOutboxRelay
{
private readonly IOutboxManager _outboxManager;
private readonly IBusClient _busClient;
private readonly ILogger<OutboxRelay> _logger;
public OutboxRelay(IOutboxManager outboxManager,
IBusClient busClient,
ILogger<OutboxRelay> logger)
{
_outboxManager = outboxManager ?? throw new ArgumentNullException(nameof(outboxManager));
_busClient = busClient ?? throw new ArgumentNullException(nameof(busClient));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
}
As you can see, instead of throwing an exception while trying to create OutboxRelay
instance it simply injects null to IOutboxManager
which is not registered in DI. Can I change the default behaviour so that exception will be thrown when trying to resolve an instance of OutboxRelay
?
Upvotes: 4
Views: 1057
Reputation: 30025
I don't think it's possible.
Since IOutboxManager
is reference type
, it's ok to define something like IOutboxManager outboxManager = null
. Then in the constructor public OutboxRelay(IOutboxManager outboxManager,xxx)
, it's ok to pass null
for the parameter outboxManager
regardless of the IOutboxManager
is registered in DI or not. You should always use ?? operator
to determine throwing an error or not.
Upvotes: 1