You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#的CompositionRoot类中访问IConfiguration读取连接字符串?

解决CompositionRoot中访问IConfiguration的问题

这个问题其实挺常见的——当我们把服务配置拆分到独立的CompositionRoot类来遵守单一职责原则时,经常会碰到需要读取配置的场景。我给你两种靠谱的解决方案,你可以根据自己的代码风格和需求来选:

方案一:显式传递IConfiguration(清晰可控)

这种方式最直接,把你已经构建好的IConfiguration实例主动传给CompositionRoot,完全掌控配置的来源。

修改步骤:

  1. 更新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)); 
    } 
}
  1. 修改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(); 
    } 
}
  1. 更新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、环境变量等),我们可以直接在注册服务的工厂方法里从容器获取配置。

修改步骤:

  1. 更新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);
        }); 
    } 
}
  1. 确保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();
}
  1. Program.cs的调用和方案一一致,把构建好的配置传给BuildHost即可。

这种方案更符合依赖注入的设计思想,不需要额外传递参数,代码更简洁。如果你的配置逻辑和Host默认逻辑一致,甚至可以简化掉传递配置的步骤,直接用Host默认加载的配置。

内容的提问来源于stack exchange,提问作者user5405648

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 13:37:38