Во время начальной загрузки моего приложения я регистрирую в основном переходные процессы и типы областей с инфраструктурой Injection Dependency, которая поставляется с .Net Core. Тем не менее, у меня есть один тип, который зарегистрирован как singleton, это мой InProcessBus
(я использую архитектуру CQRS в стиле).IServiceProvider.GetSingleton, разрешающий нуль в Asp.Net Core DI
services.AddSingleton<InProcessBus>(new InProcessBus());
...
services.AddSingleton<ICommandSender>(y => y.GetService<InProcessBus>());
services.AddSingleton<IEventPublisher>(y => y.GetService<InProcessBus>());
Как вы можете видеть, я использую реализацию фабричных функции для фактических типов, которые будут использоваться в контроллере из API. Действительно странная вещь, когда контроллер загружается, и среда выполнения пытается построить инжектор ICommandSender
, он не может его решить и сообщает об ошибке.
Если я проверил serviceCollection
, я вижу, что реализацияFactory правильно зарегистрирована по типу под свойством ImplementationInstance
.
Углубляясь и прямое разрешением типа в конце ConfigureServices()
метода Startup
класса утверждает, что контейнер разрешение null
.
ServiceLocator.GetService<ICommandSender>() // Is Null
Почему метод ImplementationFactory против синглтона, который явно существует в контейнере, не разрешается во время выполнения?
Это странно. Хотя вы можете избежать использования 'y.GetService()' и использовать 'y.GetRequiredService()', который будет генерировать исключение, если оно не может быть разрешено, а не возвращать null. Хотя это, вероятно, не решит вашу проблему. Есть ли еще больше? Также вы не можете разрешить его внутри 'ConfigureServices', в то время контейнер еще не построен. Раньше точка, которую вы можете разрешить, находится в режиме 'Configure' (если вы используете стандартный Startup.cs, который поставляется с шаблонами) –
Tseng
Вы уверены, что хотите использовать встроенный контейнер? Стили архитектуры CQRS очень эффективны, так как они действительно упрощают использование сквозных проблем с использованием декораторов. Невозможно применять родовые декораторы, используя встроенный контейнер. – Steven
@Tseng, спасибо за подсказку GetRequiredService, явное исключение лучше нуля. Обычно я не мог бы разрешить да, но я использовал BuildServiceProvider() для создания собственного провайдера для тестирования с встроенным, когда у меня возникла проблема ... –