Szymon Tomczyk
Szymon Tomczyk

Reputation: 1319

Microsoft.Extensions.DependencyInjection injects null to constructor instead of throwing an exception when service is missing

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));
    }
}

Debugging

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

Answers (1)

Ivan Glasenberg
Ivan Glasenberg

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

Related Questions