Microsoft.Extensions.DependencyInjection внедряет null в конструктор вместо того, чтобы выдавать исключение, когда служба отсутствует - PullRequest
1 голос
/ 24 февраля 2020

Microsoft DI для Azure Функции с использованием 3.0 работают довольно удивительно. Он вставляет нуль, если служба не находится, а не создает исключение. Это происходит только для подчиненных зависимостей (не root), в приведенном ниже случае, если какой-либо параметр конструктора OutboxRelay отсутствует, DI разрешает его как ноль вместо того, чтобы выдавать исключение, что служба не зарегистрирована.

У меня есть следующая Azure Функция 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)
    {
    }
}

Я настроил DI с использованием контейнера Microsoft:

    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:

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

Как видите, вместо создания исключения при попытке создать экземпляр OutboxRelay он просто вводит ноль в IOutboxManager, который не зарегистрирован в DI. Могу ли я изменить поведение по умолчанию, чтобы исключение возникало при попытке разрешить экземпляр OutboxRelay?

1 Ответ

1 голос
/ 27 февраля 2020

Я не думаю, что это возможно.

Поскольку IOutboxManager равно reference type, можно определить что-то вроде IOutboxManager outboxManager = null. Затем в конструкторе public OutboxRelay(IOutboxManager outboxManager,xxx) можно передать null для параметра outboxManager независимо от того, зарегистрировано IOutboxManager в DI или нет. Вы всегда должны использовать ?? operator, чтобы определить выбрасывание ошибки или нет.

...