.NET 6中ServiceStack IAppSettings读取配置返回Null问题
解决ServiceStack Core 5.12.0 + .NET 6中IAppSettings注入无法读取Appsettings.json的问题
问题场景
技术栈:基于ServiceStack.Core 5.12.0的微服务、C#、.NET 6(从.NET Framework 4.5升级而来)
Appsettings.json内容:
{ "username" : "test@test.com" }
配置代码:
public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IAppSettings, AppSettings>(); }
Configure方法:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseServiceStack( new HttpServiceHost { AppSettings = new NetCoreAppSettings(Configuration) }); }
Host类:
public class HttpServiceHost : AppHostBase { public HttpServiceHost () : base("Test Service" , typeof(somehandler).Assembly){} }
非处理器类TestConfig读取配置:
public class TestConfig { public TestConfig (IAppSettings setting) { // 此处始终返回Null this.UserName = setting.GetString("username"); // 但此处可以正常获取值 this.UserName = HostContext.AppSettings.GetString("username"); } public string UserName {get;set;} }
调用TestConfig的代码:
var testConfig = new TestConfig (new AppSettings());
问题原因
- 手动实例化的AppSettings不关联.NET 6配置系统:直接
new AppSettings()创建的实例,默认不会读取.NET 6的appsettings.json配置,自然读不到username的值。 - DI注册的IAppSettings与HostContext实例不一致:ConfigureServices中注册的是
AppSettings类型,而HostContext中使用的是NetCoreAppSettings(Configuration),两者不是同一个实例,且AppSettings未绑定appsettings.json配置源。 - HostContext.AppSettings是正确关联配置的实例:Configure方法中给ServiceStack Host设置的
NetCoreAppSettings(Configuration)已经绑定了appsettings.json,所以通过HostContext能正常读取。
解决方案
1. 统一注册正确的IAppSettings实例
修改ConfigureServices,注册关联.NET 6配置系统的NetCoreAppSettings作为IAppSettings的实现:
public void ConfigureServices(IServiceCollection services) { // 注册NetCoreAppSettings,关联Configuration以读取appsettings.json services.AddSingleton<IAppSettings>(provider => new NetCoreAppSettings(Configuration)); }
同时调整Configure方法,从DI容器获取已注册的IAppSettings,保持与HostContext的实例一致:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { var appSettings = app.ApplicationServices.GetRequiredService<IAppSettings>(); app.UseServiceStack( new HttpServiceHost { AppSettings = appSettings }); }
2. 通过DI容器获取TestConfig,禁止手动实例化
首先将TestConfig注册到DI容器:
public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IAppSettings>(provider => new NetCoreAppSettings(Configuration)); // 注册TestConfig到DI容器 services.AddSingleton<TestConfig>(); }
然后在需要使用TestConfig的地方,通过构造注入或者从容器解析,而非手动new:
// 示例1:在其他服务类中构造注入 public class SomeBusinessService { private readonly TestConfig _testConfig; public SomeBusinessService(TestConfig testConfig) { _testConfig = testConfig; // 此时_testConfig.UserName已正确读取到配置值 } } // 示例2:从ServiceProvider直接获取 var serviceProvider = app.ApplicationServices; var testConfig = serviceProvider.GetRequiredService<TestConfig>();
这样TestConfig的构造函数会自动注入DI容器中已注册的NetCoreAppSettings实例,就能正常读取appsettings.json中的username值。
内容的提问来源于stack exchange,提问作者A_0
相关产品推荐
相关产品推荐

