Azure函数应用中在Startup类外调用IConfigurationBuilder.Build()是否有问题?
项目场景与配置说明
我们在Azure函数应用项目中使用Azure App Configuration,为了给开发者提供顺畅的体验,仅在local.settings.json中保留连接字符串和调试客户端配置,示例如下:
{ "IsEncrypted": false, "Values": { "AzureFunctionsJobHost__logging__logLevel__Evn": "Trace", "FUNCTIONS_WORKER_RUNTIME": "dotnet", "AzureWebJobsStorage": "", "AppConfig": "Endpoint=***;Id=***", "Client": "clientId", } }
核心扩展方法实现
为了让local.settings.json的配置优先于Azure App Configuration(方便开发者将部分配置指向本地数据库、存储账户等),我们实现了以下扩展方法:
AddAppConfiguration 扩展方法
public static void AddAppConfiguration(this IConfigurationBuilder configurationBuilder, string client = null) { if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("AppConfig"))) { configurationBuilder.AddAzureAppConfiguration(options => { options.Connect(Environment.GetEnvironmentVariable("AppConfig")) .Select(KeyFilter.Any, LabelFilter.Null) .Select(KeyFilter.Any, client ?? Environment.GetEnvironmentVariable("Client")); }); configurationBuilder.PrioritizeAppSettings(); configurationBuilder.SetEnvironmentVariableFromAzureIfNotExists("AzureWebJobsStorage"); } }
PrioritizeAppSettings 扩展方法
private static void PrioritizeAppSettings(this IConfigurationBuilder builder) { // appsettings.json var appsettingsJson = builder.Sources.Where(x => x.GetType() == typeof(JsonConfigurationSource)).ToList(); foreach (var source in appsettingsJson) { builder.Sources.Remove(source); builder.Sources.Add(source); } // local.settings.json var environmentJson = builder.Sources.Where(x => x.GetType() == typeof(EnvironmentVariablesConfigurationSource)).ToList(); foreach (var source in environmentJson) { builder.Sources.Remove(source); builder.Sources.Add(source); } }
在Startup中的调用
class Startup : FunctionsStartup { public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder) { builder.ConfigurationBuilder.AddAppConfiguration(); } public override void Configure(IFunctionsHostBuilder builder) { // add services } }
问题与解决方案
我们遇到的问题是:AzureWebJobsStorage配置值为空字符串时,希望自动从Azure App Configuration中获取对应值。为此实现了以下方法:
private static void SetEnvironmentVariableFromAzureIfNotExists(this IConfigurationBuilder builder, string key) { if (string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(key))) { builder.Build().Providers .FirstOrDefault(p => p.GetType().Name == "AzureAppConfigurationProvider") .TryGet(key, out var constring); if (!string.IsNullOrWhiteSpace(constring)) Environment.SetEnvironmentVariable(key, constring); } }
该方法在AddAppConfiguration()中PrioritizeAppSettings()之后调用,目前本地运行正常,但存在疑问:在Startup类外调用builder.Build()是否存在问题? 因为.NET底层似乎也会执行类似的构建操作。
内容的提问来源于stack exchange,提问作者Clayton Treder
相关产品推荐
相关产品推荐

