【问题标题】:services.AddSingleton<IConfiguration> purpose in .NET Core.NET Core 中的 services.AddSingleton<IConfiguration> 用途
【发布时间】:2019-11-12 22:02:29
【问题描述】:

我们需要根据本地与否读取多个应用设置。我们通过添加appsettings.local.json 实现了这一点。

但是我们看到,虽然我们添加了这个文件并设置了必要的配置,但我们无法从appsettings.local.json 读取配置数据,它一直看到appsettings.json

让我通过代码告诉:

public static void Main(string[] args)
{
    var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json")
        .AddJsonFile("appsettings.local.json", optional: true)
        .AddEnvironmentVariables()
        .AddCommandLine(args)
        .Build();

    CreateWebHostBuilder(args, config).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args, IConfiguration config)
{
    var webHostBuilder = WebHost.CreateDefaultBuilder(args)
        .UseApplicationInsights()
        .ConfigureServices(services => services.AddSingleton<IConfiguration>(config))
        .UseStartup<Startup>();

    return webHostBuilder;
}

CreateWebHostBuilder 中,如果我们不添加.ConfigureServices(services =&gt; services.AddSingleton&lt;IConfiguration&gt;(config)),我们将无法从appsettings.local.json 读取数据。添加后,我们可以阅读appsettings.local.json。所以我的问题是这里发生了什么?谁能给个合理的解释?

【问题讨论】:

    标签: c# asp.net-core asp.net-core-2.0


    【解决方案1】:

    您所做的是创建一个单独的配置构建器来加载其自己的源。尽管默认 Web 主机构建器已经包含一些配置源,包括 appsettings.jsonappsettings.&lt;environment&gt;.json 文件,但您还是这样做了。

    通过说services.AddSingleton&lt;IConfiguration&gt;(config),您实际上是在用您自己的配置替换默认配置。虽然这在大多数情况下可能会产生正确的效果,但我可以想象它可能会在以后导致一些问题,因为您的应用程序中实际上有两种不同的配置(尽管其中一种 - 默认配置 - 几乎无法访问)。

    我通常建议您不要这样做,而是更改默认配置,以便它加载您所需的所有源。你可以拨打WebHostBuilder.ConfigureAppConfiguration

    public static IWebHostBuilder CreateWebHostBuilder(string[] args, IConfiguration config)
    {
        var webHostBuilder = WebHost.CreateDefaultBuilder(args)
            .UseApplicationInsights()
            .ConfigureAppConfiguration(config =>
            {
                config.AddJsonFile("appsettings.local.json", optional: true);
            })
            .UseStartup<Startup>();
    
        return webHostBuilder;
    }
    

    现在这会将另一个 JSON 文件添加到默认配置生成器。因此默认的IConfiguration 也会从该源获取配置值。这样,您就不需要在您的 Program.cs 中创建 ConfigurationBuilder

    请注意,appsettings.local.json 现在是最后一个配置源,因此在那里配置的任何设置都将覆盖之前配置的设置。因此,如果您使用命令行参数或环境变量,请注意这一点。

    最后请注意,如果您打算仅在特定的本地环境中使用 local 文件,那么您也可以在默认配置设置中仅使用 set the hosting environment to be local 自动加载 appsettings.local.json。这是因为默认主机生成器会自动选择appsettings.&lt;environment&gt;.json(如果存在)。

    【讨论】:

    • 感谢您的回答。据我了解,您建议不要用我自己的配置替换默认配置。而是更改(通过使用 ConfigureAppConfiguration)默认配置。你说。但是你说(although one of them—the default one—is mostly inaccessible)我无法理解这一点。我们可以使用其中的 2 个,如果本地 appsetting 中没有 config Key,它可以从原始应用设置中读取
    • 您必须在此处区分配置(即IConfiguration)和配置源:默认配置使用一些默认配置源(appsettings.jsonappsettings.&lt;environment&gt;.json、环境变量等)。在您的自定义配置中,您还使用了一些配置源(appsettings.jsonappsettings.local.json、环境变量、命令行参数)。两种配置都使用appsettings.json 作为源,因此如果以后的源不覆盖某个值,则将使用来自appsettings.json 的值。
    • 通过AddSingleton(config),您现在将默认配置(其来源)替换为您的自定义配置(使用这些新来源)。因此,大多数情况下都阻止了对旧配置对象的访问。这意味着在访问配置时将使用您的新来源。
    • 哟说在自定义配置中“所以如果以后的源不覆盖一个值,将使用来自 appsettings.json 的值”,但它不是也可用于默认配置吗?我认为默认配置也会发生相同的行为。我错过了stg吗?
    • 是的,多个来源的行为是一样的:后面的来源可以覆盖早期的来源。所以默认配置的工作方式相同。只需用您的自定义配置替换默认配置,您就可以有效地完全禁用默认配置。所以到那时,只有您的自定义配置很重要。
    猜你喜欢
    • 2018-03-16
    • 2019-12-31
    • 2019-04-02
    • 2019-09-11
    • 1970-01-01
    • 2016-11-06
    • 1970-01-01
    • 2019-07-27
    • 2010-09-24
    相关资源
    最近更新 更多