Потому что то, что вы делаете, не имеет смысла.
Вы регистрируете промежуточное ПО с зависимостью от сервиса, который вы пометили как временный, то есть create-on-demand.
Но промежуточное ПО всегда запускается при запуске приложения (singleton) . Поэтому любые зависимости также создаются при запуске приложения. Следовательно, экземпляр вашей «временной» службы, созданной вашим промежуточным программным обеспечением, также является одноэлементным!
Кроме того, если ваше промежуточное программное обеспечение является единственной вещью, которая зависит от этой временной службы, то зарегистрируйте службу как что-либо, кроме одиночной. бессмысленно!
То, что у вас есть, это несоответствие образа жизни иждивенцев, , что, как правило, плохая идея по многим причинам . Чтобы избежать этого, как указано выше, убедитесь, что все сервисы в вашей цепочке зависимостей зарегистрированы в одной и той же области видимости, то есть все, от чего зависит ваш ExceptionMiddleware
- в данном случае AuditedMailerService
- должно быть одноэлементным .
Если - , если - вы неявно намереваетесь или хотите, чтобы AuditedMailerService
был переходным процессом, тогда вместо внедрения его в конструктор промежуточного программного обеспечения вставьте его через Invoke
method :
public ExceptionMiddleware(RequestDelegate next, IOptions<ExceptionMiddlewareConfig> config)
{
_mailer = mailer;
_anonymousUserName = config.Value.AnonymousUserName;
_sendToEmailAddress = config.Value.SendToEmailAddress;
}
public async Task Invoke(HttpContext httpContext, IMailerService mailer)
{
...
}
Но вот еще один интересный вопрос, вытекающий из симптомов этого несоответствия образа жизни: почему экземпляр IOptions<MailerConfig>
в итоге становится null
?
Мое предположение - и это только предположение - заключается в том, что вы попали в тупик из-за того, что ASP. NET Core 2.x's WebHost
(компонент, который запускает ваш веб-приложение) фактически создает два IServiceProvider
экземпляров . Существует первоначальный «фиктивный», который создается для внедрения сервисов на самых ранних этапах запуска приложения, а затем «реальный», который используется до конца жизни приложения. Связанная проблема обсуждает, почему это проблематично c: короче говоря, было возможно получить экземпляры службы, зарегистрированные в фиктивном контейнере, тогда реальный контейнер создал бы второй экземпляр той же службы, вызывая проблемы. Я полагаю, что поскольку промежуточное программное обеспечение запускается так рано в конвейере, контейнер Io C, который он использует, является фиктивным без знания IOptions<MailerConfig>
и , поскольку расположение службы по умолчанию в ASP. NET Core. возвращает null
, когда запрашиваемая служба не найдена, вместо выдачи исключения , возвращается null
.