Sar*_*zen 0 .net dependency-injection asp.net-core-mvc .net-core asp.net-core
在ConfigureServices()我的应用程序的引导过程中,我使用 .Net Core 附带的依赖注入框架注册了大部分瞬态和作用域类型。但是,我确实有一种注册为单例的类型是我的InProcessBus(我使用的是 CQRS 风格的架构)。
services.AddSingleton<InProcessBus>(new InProcessBus());
...
services.AddSingleton<ICommandSender>(y => y.GetService<InProcessBus>());
services.AddSingleton<IEventPublisher>(y => y.GetService<InProcessBus>());
Run Code Online (Sandbox Code Playgroud)
如您所见,我正在为将在 API 的控制器中使用的实际类型使用实现工厂函数。真正奇怪的是,当控制器加载并且运行时尝试构造函数注入时,ICommandSender它无法解决它并报告错误。
如果我检查serviceCollection我可以看到 implementationFactory 已针对ImplementationInstance属性下的类型正确注册。
在Startup类的ConfigureServices()方法末尾深入和直接解析类型确认容器正在解析null.
ServiceLocator.GetService<ICommandSender>() // Is Null
Run Code Online (Sandbox Code Playgroud)
为什么针对明显存在于容器中的单例的 ImplementationFactory 方法不会在运行时解析?
我发现出了什么问题,并认为我会把它贴在这里,因为其中有一个重要的教训。
简短的回答:
serviceCollection.BuildServiceProvider()在您注册所有单例实例后推迟,否则将无法解析它们。
长答案:
该问题实际上与 asp 核心 DI 容器无关(很好)。问题是,当我打电话的时间BuildServiceProvider上的serviceCollection实例来为我提供IServiceProvider。
在我的实现中,我实现了一个ServiceLocator模式,该模式包装了核心附带的 DI 框架,这样我就不会在我的其他架构层中引入额外的依赖项。当我构建我的IServiceContainer基于定位器时,我立即解决了ServiceProvider
public ServiceLocator(
IServiceCollection serviceCollection)
{
_serviceCollection = serviceCollection;
_serviceProvider = _serviceCollection.BuildServiceProvider();
}
Run Code Online (Sandbox Code Playgroud)
这是哪里出了问题蹑手蹑脚。当时间ServiceProvider明显创建是不打紧的Transients和Scoped实例。但是对于有管理生命周期的单身人士来说,它确实如此。您需要推迟ServiceProviders所有注册后的创建。
从我的问题来看,它ServiceLocator是在片段之前构造的,这意味着ServiceProvider当 implementationFactory 函数执行时,单例实例将无法访问。
通过将 ServiceProvider 的创建推迟到我的应用程序第一次在运行时解析我的自定义类型时,解决了这个问题。
| 归档时间: |
|
| 查看次数: |
4296 次 |
| 最近记录: |