如何在WPF Prism应用中读取appsettings.json配置文件
Prism应用等价实现HostBuilder配置加载方案
Prism自带的容器抽象与初始化生命周期完全可以覆盖HostBuilder在WPF场景下的所有能力,无需强行集成HostBuilder,避免两套容器生命周期冲突的问题。
核心逻辑对应关系
HostBuilder在WPF场景下的核心作用只有三点,完全可以平移到Prism的初始化管道中实现:
- 加载多源配置,构建
IConfiguration实例 - 完成服务、配置选项、DbContext、业务实现的依赖注入注册
- 配置日志提供器
前置准备
先安装和原HostBuilder方案完全一致的NuGet包:
Microsoft.Extensions.ConfigurationMicrosoft.Extensions.Configuration.JsonMicrosoft.Extensions.Options.ConfigurationExtensionsMicrosoft.Extensions.Logging- 按需安装EF Core、其他日志提供器等相关包
同时将项目中的appsettings.json文件属性设置为如果较新则复制到输出目录,和原HostBuilder方案要求一致。
完整实现代码
重写Prism应用类即可,代码如下:
public partial class App : PrismApplication { private IConfiguration _appConfiguration; protected override void OnStartup(StartupEventArgs e) { // 等价于HostBuilder的ConfigureAppConfiguration逻辑,优先加载配置 var configBuilder = new ConfigurationBuilder(); var executingPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); configBuilder.SetBasePath(executingPath); configBuilder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); // 如需添加环境变量、命令行等其他配置源,直接在此处追加即可 _appConfiguration = configBuilder.Build(); base.OnStartup(e); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { // 注册配置实例,等价于services.AddSingleton<IConfiguration> containerRegistry.RegisterInstance(_appConfiguration); // 注册强类型配置选项,等价于services.Configure<AppSettings> containerRegistry.RegisterInstance(Options.Create(_appConfiguration.Get<AppSettings>())); // 注册DbContext,生命周期和原AddScoped逻辑完全对齐 containerRegistry.RegisterScoped<VisitorDbContext>(_ => { var dbOptionBuilder = new DbContextOptionsBuilder<VisitorDbContext>(); dbOptionBuilder.UseSqlServer(_appConfiguration.GetConnectionString("DefaultConnection")); return new VisitorDbContext(dbOptionBuilder.Options); }); // 注册业务服务,和原服务注册逻辑一一对应 containerRegistry.RegisterScoped<ISampleService, SampleService>(); containerRegistry.RegisterScoped<IImportService, ImportService>(); // 注册日志相关组件,等价于HostBuilder的ConfigureLogging逻辑 var loggerFactory = LoggerFactory.Create(logBuilder => { // 按需添加日志提供器,例如logBuilder.AddDebug()、logBuilder.AddFile()等 // logBuilder.AddConsole(); }); containerRegistry.RegisterInstance<ILoggerFactory>(loggerFactory); containerRegistry.Register(typeof(ILogger<>), typeof(Logger<>)); // 注册主窗口 containerRegistry.RegisterSingleton<MainWindow>(); } protected override Window CreateShell() { // 从容器解析主窗口作为启动外壳,等价于Host构建后获取MainWindow启动的逻辑 return Container.Resolve<MainWindow>(); } }
补充说明
上述实现兼容Prism 8.x及以上版本,无论你使用DryIoc还是Unity作为底层容器,都不需要修改注册逻辑,Prism的IContainerRegistry已经做了统一适配。
Prism官方不推荐强行集成HostBuilder的核心原因是:Prism本身已经具备完整的依赖注入容器、模块化加载、导航管理生命周期,强行嵌入HostBuilder会出现两套独立容器并存的问题,极易引发服务解析冲突、生命周期不匹配的异常,直接将HostBuilder的非Web能力平移到Prism初始化管道是更稳定、更符合框架设计的方案。
内容的提问来源于stack exchange,提问作者Nearshore
相关产品推荐
相关产品推荐

