如何在MAUI的MauiProgram.cs中获取已注册的DI服务实例?
在MAUI的MauiProgram.cs中获取已注册的DI服务实例
MAUI的依赖注入配置逻辑和ASP.NET Core的Startup.cs类似,默认在MauiProgram.cs文件中完成服务注册。当前的问题是:注册服务后,如何在该文件内优雅获取服务实例,避免手动实例化带来的构造函数变更同步修改问题。
当前的非优雅实现:
var keyValueStore = new PreferencesKeyValueStore(); var accountService = new AccountService(keyValueStore); var profileService = new ProfileService(keyValueStore); builder.Services.AddSingleton<IKeyValueStore>(keyValueStore); builder.Services.AddSingleton<IAccountService>(accountService); builder.Services.AddSingleton<IProfileService>(profileService); // 此处可直接使用实例
期望的优雅实现(但不知道如何操作):
builder.Services.AddSingleton<IKeyValueStore, PreferencesKeyValueStore>(); builder.Services.AddSingleton<IAccountService, AccountService>(); builder.Services.AddSingleton<IProfileService, ProfileService>(); // 期望能直接从DI容器获取实例:var accountService = diContainer.GetInstance<IAccountService>();
解决方案1:构建临时服务提供者获取实例
通过IServiceCollection.BuildServiceProvider()方法创建服务容器,从中获取已注册的服务实例:
// 1. 完成所有服务注册 builder.Services.AddSingleton<IKeyValueStore, PreferencesKeyValueStore>(); builder.Services.AddSingleton<IAccountService, AccountService>(); builder.Services.AddSingleton<IProfileService, ProfileService>(); // 2. 构建服务提供者 var serviceProvider = builder.Services.BuildServiceProvider(); // 3. 获取服务实例(GetRequiredService会在服务不存在时抛出异常,也可使用GetService<T>()返回null) var accountService = serviceProvider.GetRequiredService<IAccountService>(); var profileService = serviceProvider.GetRequiredService<IProfileService>(); // 执行所需操作 accountService.Initialize(); profileService.LoadDefaultProfile();
解决方案2:通过构建后的应用实例获取(推荐)
MAUI的builder.Build()会返回应用实例,其Services属性就是应用运行时使用的服务容器,通过它获取的实例和应用内使用的是同一个单例:
// 1. 注册所有服务 builder.Services.AddSingleton<IKeyValueStore, PreferencesKeyValueStore>(); builder.Services.AddSingleton<IAccountService, AccountService>(); builder.Services.AddSingleton<IProfileService, ProfileService>(); // 2. 构建应用实例 var app = builder.Build(); // 3. 从应用服务容器获取实例 var accountService = app.Services.GetRequiredService<IAccountService>(); accountService.PerformInitialSetup(); // 4. 启动应用 app.Run();
这种方式避免了创建临时服务容器可能导致的单例实例不一致问题,更贴合MAUI的生命周期逻辑。
内容的提问来源于stack exchange,提问作者Miloš
相关产品推荐
相关产品推荐

