trying to set config value `IHostBuilder` but not reflected for ConfigureServices in Startup class - asp.net core 3.1

好久不见. 提交于 2021-02-05 08:52:08

问题


I have below config with empty connection string,

"ConnString": {
"Value":  "" 
},

Now in Asp.Net Core 3.1 app I am trying to set the connection string value inside CreateHostBuilder

public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.ConfigureAppConfiguration((context, config) =>
                {
                    var settings = config.Build();
                    settings["ConnString:Value"] = "MY CONNECTION STRING";

                });

                webBuilder.UseStartup<Startup>();
            });

But this value is NOT reflected in ConfigureServices method of Startup class, it is still showing empty. What should I need to do here? please suggest!

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
    {
        var updateValue = Configuration.GetSection("ConnString:Value").Value;
    }

回答1:


You are building the configuration and setting the value on the new IConfiguration object. However these settings will be lost as you aren't setting the values on the builder. The underlying infrastructure calls Build again later which creates another new IConfiguration. The values don't magically transfer over.

What you can do instead is call AddInMemoryCollection and pass your new settings there. This will then get consumed by the infrastructure and be made available later (ie in ConfigureServices):

webBuilder.ConfigureAppConfiguration((context, config) =>
{
   config.AddInMemoryCollection(
     new [] { 
       new KeyValuePair<string, string>("ConnString:Value", "MY CONNECTION STRING") 
     }
   );
});

IWebHostBuilder also has a UseSetting method where you can configure a single setting. This adds a new in-memory configuration provider containing just one value:

webBuilder.UseSetting("ConnString:Value", "MY CONNECTION STRING");

Note that the IWebHostBuilder will consume the configuration from the IHostBuilder (the generic host). You could alternatively call ConfigureAppConfiguration on the host builder instead.

Host.CreateDefaultBuilder(args) 
    .ConfigureAppConfiguration((context, config) =>
     {
        config.AddInMemoryCollection(
          new [] { 
            new KeyValuePair<string, string>("ConnString:Value", "MY CONNECTION STRING") 
          }
        );
     });

This "injection" is particularly useful if you have settings that are used to configure other settings. You could instead add them in ConfigureHostConfiguration (which doesn't exist for IWebHostBuilder) allowing their values to be available within ConfigureAppConfiguration on either builder.

Note that the configuration isn't shared back to the host builder. Any configuration you add to the web host doesn't automatically apply to the generic host. I call this out because it is different from the behavior of the ServiceCollection which is shared between the two (adding services to one adds to the other).

Update based on your comments:

I mentioned above that ConfigureHostConfiguration can be used if you have settings used to configure/setup other configuration providers. This is particularly useful for something like configuring Azure KeyVault.

Host.CreateDefaultBuilder(args) 
    .ConfigureHostConfiguration(config =>
     {
        // setup bootstrapping settings. For example if we need to add in values used
        // to configure azure key vault stored in app settings and maybe some in memory 
        config.AddJsonFile("appsettings.json");
        config.AddInMemoryCollection(
          new [] { 
            new KeyValuePair<string, string>("ClientId", "AzureClientId"), 
            new KeyValuePair<string, string>("TenantId", "AzureTenantId") 
          }
        );
     })
     // settings added in ConfigureHostConfiguration are now available via context.Configuration
    .ConfigureAppConfiguration((context, config) =>
     {
         // use the values we added during bootstrapping 
         var tenant = context.Configuration["TenantId"];
         var client = context.Configuration["ClientId"];
         // example, I don't remember the parameters off-hand
         config.AddAzureKeyVault(tenant, client, /*etc*/);
     });

In this example ConfigureAppConfiguration could also be called on the IWebHostBuilder instead.

For more information about configuration and the generic host, see the documentation.



来源:https://stackoverflow.com/questions/62636075/trying-to-set-config-value-ihostbuilder-but-not-reflected-for-configureservice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!