我们正在使用
Azure应用程序配置
和
Azure密钥库
从加载配置。过去有四种环境:
Development
,
QA
,
Staging
,
Production
,但现在我们也有
Local
环境。以前,我们使用
发展
为了地方发展,但现在
本地
是当地的。
问题是
secrets.json
未加载
本地
环境。它只加载
发展
.
本地环境配置源:
builder.Sources = ConfigurationManager.ConfigurationSources
[0] = MemoryConfigurationSource
[1] = EnvironmentVariablesConfigurationSource
[2] = EnvironmentVariablesConfigurationSource
[3] = JsonConfigurationSource ("appsettings.json")
[4] = JsonConfigurationSource ("appsettings.Local.json")
[5] = EnvironmentVariablesConfigurationSource
[6] = ChainedConfigurationSource
开发环境配置源:
builder.Sources = ConfigurationManager.ConfigurationSources
[0] = MemoryConfigurationSource
[1] = EnvironmentVariablesConfigurationSource
[2] = EnvironmentVariablesConfigurationSource
[3] = JsonConfigurationSource ("appsettings.json")
[4] = JsonConfigurationSource ("appsettings.Development.json")
[5] = JsonConfigurationSource ("secrets.json")
[6] = EnvironmentVariablesConfigurationSource
[7] = ChainedConfigurationSource
我做了一些研究,并基于
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-8.0#default-application-configuration-sources
:
应用程序在开发环境中运行时的用户机密
我相信
secrets.json
仅适用于
发展
默认情况下。那么,我该如何将其转化为行为
本地
环境?
using Azure.Core;
using Microsoft.Extensions.Configuration.EnvironmentVariables;
using Microsoft.Extensions.Configuration.Json;
using RJO.BuildingBlocks.Common;
using RJO.BuildingBlocks.Common.Azure;
using RJO.BuildingBlocks.Common.Azure.AppConfiguration;
using System.Text.Json;
// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.Configuration;
public static class ConfigurationBuilderExtensions
{
static readonly TimeSpan LocalCacheDuration = 24.Hours();
public static IConfigurationBuilder AddAzureAppConfiguration(this IConfigurationBuilder builder, StartupLogger logger, string endpoint)
{
var azureAppConfigurationSource = new ChainedConfigurationSource
{
Configuration = builder.GetAzureAppConfiguration(logger, endpoint)
};
var nextSource = builder.Sources.FirstOrDefault(x => x is JsonConfigurationSource or EnvironmentVariablesConfigurationSource);
if (nextSource != null)
{
// We insert the Azure source before the JSON and Environment sources so that those take precedence
var indexOfNextSource = builder.Sources.IndexOf(nextSource);
builder.Sources.Insert(indexOfNextSource, azureAppConfigurationSource);
}
else
builder.Sources.Add(azureAppConfigurationSource);
return builder;
}
static IConfiguration GetAzureAppConfiguration(this IConfigurationBuilder builder, StartupLogger logger, string endpoint)
{
const string secretsJsonFilename = "secrets.json";
if (builder.Sources.FirstOrDefault(x => x is JsonConfigurationSource { Path: secretsJsonFilename }) is not JsonConfigurationSource secretsSource)
return GetAzureAppConfiguration(logger, endpoint);
// Check that there are actually some secrets stored (to ensure that caching only works on developer machines)
var secrets = new ConfigurationBuilder().SetFileProvider(builder.GetFileProvider()).Add(secretsSource).Build().AsEnumerable();
if (!secrets.Any())
return GetAzureAppConfiguration(logger, endpoint);
var fileInfo = secretsSource.FileProvider.GetFileInfo(secretsJsonFilename);
var directory = Path.GetDirectoryName(fileInfo.PhysicalPath);
var cacheFilename = Path.Join(directory, endpoint.Replace("https://", string.Empty) + ".cached.json");
if (File.Exists(cacheFilename) && File.GetLastWriteTimeUtc(cacheFilename) > DateTime.UtcNow.Subtract(LocalCacheDuration))
{
var expiresIn = DateTime.UtcNow.Subtract(File.GetLastWriteTimeUtc(cacheFilename).Add(LocalCacheDuration)).Duration();
logger.Info($"Using cached Azure App Configuration from {cacheFilename} (expires in {expiresIn.AsDuration()}) ...");
return new ConfigurationBuilder().AddJsonFile(cacheFilename).Build();
}
logger.Info("Cached Azure App Configuration was not found or is expired ...");
var configuration = GetAzureAppConfiguration(logger, endpoint);
logger.Info($"Caching Azure App Configuration as {cacheFilename} (expires in {LocalCacheDuration.AsDuration()}) ...");
var json = JsonSerializer.Serialize(new Dictionary<string, string>(configuration.AsEnumerable()));
File.WriteAllText(cacheFilename, json);
return configuration;
}
static IConfiguration GetAzureAppConfiguration(StartupLogger logger, string endpoint)
{
logger.Info("Authenticating with Azure App Configuration ...");
var credential = AzureIdentity.HrvystCredential;
var configuration = new ConfigurationBuilder()
.AddAzureAppConfiguration(options => options
.ConfigureClientOptions(x => x.AddPolicy(new LoggingPolicy(logger), HttpPipelinePosition.PerRetry))
.Connect(new Uri(endpoint), credential)
.ConfigureKeyVault(x => x.SetCredential(credential)))
.Build();
logger.Info("Finished loading Azure App Configuration.");
return configuration;
}
}