ServiceStack IDE执行迁移时连接字符串解析失败问题排查
我正按照ServiceStack文档指导,通过测试类在IDE中执行数据库迁移,但ResolveDbFactory方法报错提示连接字符串为空。
我的主项目中ConfigureDb类实现如下:
public class ConfigureDb : IHostingStartup { public void Configure(IWebHostBuilder builder) => builder .ConfigureServices((context, services) => { services.AddSingleton<IDbConnectionFactory>(new OrmLiteConnectionFactory( context.Configuration.GetConnectionString("DefaultConnection"), SqlServer2019Dialect.Provider)); }); }
其中DefaultConnection来自AppHost中配置的appsettings.secrets.json文件,AppHost配置如下:
public class AppHost : AppHostBase, IHostingStartup { public void Configure(IWebHostBuilder builder) => builder .ConfigureAppConfiguration((hostingContext, config) => { config.AddJsonFile("appsettings.secrets.json", optional: true, reloadOnChange: true); }) .ConfigureServices(services => { // Configure ASP.NET Core IOC Dependencies services.AddScoped<IEmailFactory, EmailFactory>(); services.AddScoped<IEmailSender, SendGridEMailSender>(); }); }
为何调用static IDbConnectionFactory ResolveDbFactory() => new ConfigureDb().ConfigureAndResolve<IDbConnectionFactory>();无法解析连接字符串?
原因分析
直接实例化ConfigureDb并调用ConfigureAndResolve时,并未加载AppHost中配置的appsettings.secrets.json配置源,导致context.Configuration里找不到DefaultConnection连接字符串,最终返回空值。
ConfigureAndResolve仅会执行当前IHostingStartup的Configure逻辑,不会自动关联其他IHostingStartup(比如你的AppHost)的配置,因此整个配置体系并未加载到你的秘密文件。
解决方案
方案1:手动加载配置源构建连接工厂
修改ResolveDbFactory方法,手动构建配置并加载appsettings.secrets.json,直接创建连接工厂:
static IDbConnectionFactory ResolveDbFactory() { var config = new ConfigurationBuilder() .AddJsonFile("appsettings.secrets.json", optional: true, reloadOnChange: true) .Build(); return new OrmLiteConnectionFactory( config.GetConnectionString("DefaultConnection"), SqlServer2019Dialect.Provider); }
方案2:完整启动Host解析依赖
如果需要复用整个Host的配置和依赖体系,可通过构建WebHost来获取IDbConnectionFactory:
static IDbConnectionFactory ResolveDbFactory() { var hostBuilder = new WebHostBuilder(); // 同时加载AppHost和ConfigureDb的配置逻辑 new AppHost().Configure(hostBuilder); new ConfigureDb().Configure(hostBuilder); var host = hostBuilder.Build(); return host.Services.GetRequiredService<IDbConnectionFactory>(); }
方案3:通过ServiceStack AppHost直接解析
如果AppHost已集成OrmLite相关配置,可直接初始化AppHost并获取连接工厂:
static IDbConnectionFactory ResolveDbFactory() { var appHost = new AppHost(); appHost.Init(); return appHost.Resolve<IDbConnectionFactory>(); }
注:需确保AppHost的配置逻辑中已正确加载appsettings.secrets.json,且完成了IDbConnectionFactory的注册(可将ConfigureDb中的注册逻辑移到AppHost的ConfigureServices方法内)。
内容的提问来源于stack exchange,提问作者Shawn de Wet

