.Net Core 2.0 IServiceProvider预初始化及Scrutor扫描DI问题咨询
如何在.NET Core 2.0中预初始化IServiceProvider中的服务
在你用Scrutor完成程序集扫描注册服务之后,预初始化本质上就是主动触发服务实例的创建(而不是等第一次依赖注入时才初始化)。下面分几种场景给你具体的实现方案:
1. 预初始化Singleton服务
因为Singleton服务在第一次被解析时就会创建实例并保持全局唯一,所以我们只需要在构建完IServiceProvider后,主动解析这些服务即可。
方法1:解析所有注册的Singleton服务
如果你想一次性初始化所有Singleton类型的服务,可以遍历服务描述符并逐个解析:
// 假设你已经完成了所有服务注册(包括Scrutor的扫描) var serviceProvider = services.BuildServiceProvider(); // 遍历所有Singleton类型的服务描述符 foreach (var descriptor in services.Where(d => d.Lifetime == ServiceLifetime.Singleton && d.ImplementationType != null)) // 排除工厂注册或实例注册的情况 { // 主动解析服务,触发初始化 serviceProvider.GetService(descriptor.ServiceType); }
方法2:只初始化特定接口的实现类
如果你只需要初始化Scrutor扫描注册的某类接口(比如你提到的指定接口),可以直接解析该接口的所有实现:
// 替换成你实际的接口类型 var myServices = serviceProvider.GetServices<IYourTargetInterface>(); // 只要获取到实例集合,就完成了所有实现类的初始化
2. 预初始化Scoped服务
Scoped服务的生命周期和Scope绑定,所以需要先创建一个临时Scope,再在Scope内解析服务:
using (var scope = serviceProvider.CreateScope()) { var scopedServiceProvider = scope.ServiceProvider; // 解析单个Scoped服务 var scopedService = scopedServiceProvider.GetRequiredService<IScopedService>(); // 或者解析所有某接口的Scoped实现 var allScopedServices = scopedServiceProvider.GetServices<IScopedInterface>(); }
3. 带自定义初始化逻辑的服务
如果你的服务需要执行特定初始化操作(比如加载配置、初始化数据库连接),建议定义一个统一的初始化接口,让需要初始化的服务实现它:
// 定义初始化接口 public interface IInitializable { // 支持同步或异步方法,根据你的需求选择 void Initialize(); // 或者 Task InitializeAsync(); } // 让你的服务实现该接口 public class MyService : IYourInterface, IInitializable { public void Initialize() { // 这里写你的自定义初始化逻辑,比如加载缓存数据 } }
然后在预初始化时,统一调用这个接口的方法:
var initializables = serviceProvider.GetServices<IInitializable>(); foreach (var initializable in initializables) { initializable.Initialize(); // 如果是异步方法:await initializable.InitializeAsync(); }
4. 在ASP.NET Core应用启动时执行预初始化
在ASP.NET Core 2.0中,你可以在Program.cs的异步Main方法中完成初始化(确保应用启动前完成所有准备工作):
public static async Task Main(string[] args) { var host = CreateWebHostBuilder(args).Build(); // 创建Scope执行初始化 using (var scope = host.Services.CreateScope()) { var serviceProvider = scope.ServiceProvider; // 执行Singleton服务初始化 var initializables = serviceProvider.GetServices<IInitializable>(); foreach (var initializable in initializables) { await initializable.InitializeAsync(); } } // 启动应用 await host.RunAsync(); }
或者也可以在Startup.cs的Configure方法中注入IServiceProvider来执行初始化:
public void Configure(IApplicationBuilder app, IServiceProvider serviceProvider) { // 先配置中间件... // 预初始化服务 var myServices = serviceProvider.GetServices<IYourInterface>(); foreach (var service in myServices) { // 如果有初始化方法就调用 if (service is IInitializable initializable) { initializable.Initialize(); } } }
内容的提问来源于stack exchange,提问作者JParks
相关产品推荐
相关产品推荐

