如何在C#的CompositionRoot类中访问IConfiguration读取连接字符串?
解决CompositionRoot中访问IConfiguration的问题
这个问题其实挺常见的——当我们把服务配置拆分到独立的CompositionRoot类来遵守单一职责原则时,经常会碰到需要读取配置的场景。我给你两种靠谱的解决方案,你可以根据自己的代码风格和需求来选:
方案一:显式传递IConfiguration(清晰可控)
这种方式最直接,把你已经构建好的IConfiguration实例主动传给CompositionRoot,完全掌控配置的来源。
修改步骤:
- 更新CompositionRoot类,让
ConfigureServices方法接收IConfiguration参数:
public static class CompositionRoot { // 添加IConfiguration参数 public static void ConfigureServices(IServiceCollection services, IConfiguration configuration) { var connectionString = configuration.GetValue<string>("ConnectionStrings.production"); services.AddSingleton<IDbConnection>(provider => new MySqlConnection(connectionString)); } }
- 修改StartupHelpers的BuildHost方法,让它接收配置实例并传递给CompositionRoot:
public static class StartupHelpers { // 其他方法不变,只修改BuildHost public static IHost BuildHost(IConfiguration configuration) { return Host.CreateDefaultBuilder() .ConfigureServices((context, services) => { // 把配置传给CompositionRoot CompositionRoot.ConfigureServices(services, configuration); }) .UseSerilog() .Build(); } }
- 更新Program.cs的调用逻辑,先构建好配置再传给BuildHost:
internal static class Program { internal static void Main() { var config = StartupHelpers.BuildConfig().Build(); // 先完成配置构建 StartupHelpers.SetupSerilog(config); var host = StartupHelpers.BuildHost(config); // 传递配置实例 host.Services.GetService<IGreetingService>()?.Run(); } }
这种方案的好处是逻辑透明,你完全清楚配置的来源,和Host默认的配置加载逻辑解耦,适合需要自定义配置源的场景。
方案二:从服务容器中获取IConfiguration(符合DI风格)
Host.CreateDefaultBuilder()会自动把IConfiguration注册到服务容器中(默认加载appsettings.json、环境变量等),我们可以直接在注册服务的工厂方法里从容器获取配置。
修改步骤:
- 更新CompositionRoot类,在工厂方法中通过
provider获取配置:
public static class CompositionRoot { public static void ConfigureServices(IServiceCollection services) { // 不需要提前声明configuration,直接从容器拿 services.AddSingleton<IDbConnection>(provider => { var configuration = provider.GetRequiredService<IConfiguration>(); var connectionString = configuration.GetValue<string>("ConnectionStrings.production"); return new MySqlConnection(connectionString); }); } }
- 确保Host使用你的自定义配置(如果
BuildConfig有自定义配置源的话):
如果你的BuildConfig添加了额外的配置源(比如自定义json文件),需要把它合并到Host的配置中,修改StartupHelpers.BuildHost:
public static IHost BuildHost(IConfiguration configuration) { return Host.CreateDefaultBuilder() .ConfigureAppConfiguration(builder => { // 将自定义配置添加到Host的配置集合中 builder.AddConfiguration(configuration); }) .ConfigureServices(CompositionRoot.ConfigureServices) .UseSerilog() .Build(); }
- Program.cs的调用和方案一一致,把构建好的配置传给
BuildHost即可。
这种方案更符合依赖注入的设计思想,不需要额外传递参数,代码更简洁。如果你的配置逻辑和Host默认逻辑一致,甚至可以简化掉传递配置的步骤,直接用Host默认加载的配置。
内容的提问来源于stack exchange,提问作者user5405648
相关产品推荐
相关产品推荐

