【问题标题】:How to inject a custom configuration processor into WebHost.CreateDefaultBuilder?如何将自定义配置处理器注入 WebHost.CreateDefaultBuilder?
【发布时间】:2020-08-28 08:41:09
【问题描述】:

我的 Program.cs 文件中有一个非常标准的 ASP.NET Core Web 应用程序初始化代码片段:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureLogging((hostingContext, logging) =>
        {
            logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
            logging.AddSerilog(dispose: true);
        })
        .UseSerilog((ctx, config) => { config.ReadFrom.Configuration(ctx.Configuration); })
        .UseStartup<Startup>();

我想插入我的自定义配置拦截器,它读取并替换配置的当前最终组合值,但我不明白该怎么做。

我们从 Microsoft 文档中了解到,CreateDefaultBuilder 使用环境特定的 json 覆盖 appsettings.json,最后使用环境变量和命令行参数覆盖它。我想在最后一步之后立即注入我的自定义代码,这样我就可以在值通过public IConfiguration Configuration { get; } 进一步向下传递给 Startup 之前拦截和修改值。

我在 ASP.NET Core 源代码中发现了一个有趣的函数:

ConfigureAppConfiguration((hostingContext, config) =>

它结合了所有来源。我不想完全覆盖它,我只想在 ConfigureAppConfiguration 完成其工作但在我的 Startup 接收配置值之前附加我自己的配置转换。

我该怎么做?

更多信息以提供一些上下文:

目标是为配置值注入自定义解密例程,这些配置值可能在这三个位置(appsettings.json、环境 json、环境变量)中的任何一个位置被加密。我只找到了通过自定义配置提供程序为 appsettings.json 实现加密的答案,但没有找到在所有组合源之后注入我的解密例程的答案。

我不是要求加密/解密例程本身(我已经拥有它们),而是要求一种解决方案,用于注入接收配置值的函数调用以用我的解密值覆盖。

【问题讨论】:

  • 您可以定义自定义扩展方法来转换构建后的配置。或者定义自定义配置源,在所有之前的源之后应用
  • @PavelAnikhouski 你能提供一个简单的例子吗?在哪里注入它以及如何在将所有配置值传递给 Startup 之前访问它们?

标签: c# asp.net-core configuration


【解决方案1】:

如果我猜对了,您想通过阅读原始资源并解密它们来获得您的IConfiguration

然后你可以使用这样的东西:

return WebHost.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration(builder =>
                {
                    // Build an IConfiguration from the currently added IConfigurationSources
                    var notEncrypted = builder.Build();

                    // Clear the currently added ones
                    builder.Sources.Clear();

                    // Add you own IConfigurationSource with the previously added IConfiguration to read all values in the encrypted form.
                    var yourConfugurationSource = new < EncryptedConfigurationSource > (notEncrypted)

                    // Add your IConfigurationSource to the App 
                    // Now every call to IConfiguration takes your source
                    builder.Add(yourConfugurationSource);
                })
                .Build();

就像一个评论。最后添加的IConfigurationSource 将作为第一个值。如果这就够了,你不需要清除自动添加的IConfigurationSources

【讨论】:

  • 谢谢,这个builder.Build() 是我错过的关键一步。我正在查看错误的ConfigureAppConfiguration((hostingContext, config) ,它无法访问构建器,因此我无法获得最新值。现在它应该可以按预期工作了。
  • 仅供参考,config ConfigureAppConfiguration((hostingContext, config) 是建设者 :)
  • 我的兴奋还为时过早——我无法直接从 notEncrypted 中获取值——IConfigurationSource 还需要一个额外的组件,即 Provider,只有它才能访问这些值。但是,原始的 notEncrypted 再次拥有所有收集的提供程序,并且很难理解如何提取和替换值。
  • 也许您也可以通过不使用ConfigureAppConfiguration 而是在DI .AddSingleton&lt;IConfiguration&gt;(sp =&gt; { notEncrypted = sp.GetRequiredService&lt;IConfiguration&gt;(); return new &lt; EncryptedConfiguration &gt; (notEncrypted)); }) 中注册您的IConfiguration 来做到这一点,但请确保最后一个IConfiguration 由IServiceProvider 获取
猜你喜欢
  • 1970-01-01
  • 2016-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多