我有一个 Azure 函数,我正在使用 DI 系统来注册一些类型;例如:
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services
.AddTransient<IMyInterface, MyClass>()
. . . etc
但是,我还要从我的环境设置中注册一些数据。在函数内部,我可以得到
ExecutionContext
,所以我可以这样做:IConfiguration config = new ConfigurationBuilder()
.SetBasePath(context.FunctionAppDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
但是,在 FunctionsStartup 中,我无权访问
ExecutionContext
.有没有办法可以从 FunctionsStartup 类中获取 ExecutionContext ,或者另一种确定当前运行目录的方法,以便我可以设置基本路径?
最佳答案
虽然对这个问题的检查答案是正确的,但我认为它缺乏关于原因的深度。您应该知道的第一件事是,在幕后,Azure 函数使用相同的 配置生成器 在 ASP.NET Core 应用程序中找到,但具有一组不同的提供程序。与 ASP.NET Core 的文档非常详细 (https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/) 不同,Azure Functions 并非如此。
要了解这组提供程序,您可以将以下代码行放入 配置(IFunctionsHostBuilder 构建器)您的方法 功能启动类(class),
var configuration = builder.Services.BuildServiceProvider().GetService<IConfiguration>();
在命令后放置一个调试断点,在 Debug模式下执行您的函数并在配置变量上执行快速观察...(右键单击变量名称以选择快速观察...)。深入代码执行的结果是以下提供程序列表。
Microsoft.Extensions.Configuration.ChainedConfigurationProvider
MemoryConfigurationProvider
HostJsonFileConfigurationProvider
JsonConfigurationProvider for 'appsettings.json' (Optional)
EnvironmentVariablesConfigurationProvider
MemoryConfigurationProvider
ChainedConfigurationProvider 添加一个现有的 IConfiguration 作为来源。在默认配置情况下,添加主机配置并将其设置为应用程序配置的第一个源。第一内存配置提供程序 添加键/值 {[AzureWebJobsConfigurationSection, AzureFunctionsJobHost]} .至少它在开发环境中是这样做的。在我写这篇文章的时候,我找不到关于这个目的的文档 内存配置提供程序 或 AzureWebJobs 配置部分 .
HostJsonFileConfigurationProvider 是另一个隐藏的无证提供者,但是在查看 上的文档时host.json ( https://docs.microsoft.com/en-us/azure/azure-functions/functions-host-json ) 它似乎负责提取此元数据。
JsonConfigurationProvider 为 appsettings.json 似乎与 ASP.NET Core 使用 有明显的相关性。 appsettings.json 除了一件事它不起作用。经过一番调查,我发现 来源 文件提供程序 根没有设置为文件所在的应用程序根文件夹,而是一些模糊的 AppData 文件夹(C:\Users%USERNANE%\AppData\Local\AzureFunctionsTools\Releases\3.15.0\cli_x64)。去钓鱼。
EnvironmentVariablesConfigurationProvider 加载环境变量键值对。
第二个内存配置提供程序 添加键/值 {[AzureFunctionsJobHost:logging:console:isEnabled, false]} .至少它在开发环境中是这样做的。同样,在我写这篇文章的时候,我找不到关于这个 目的的文档。内存配置提供程序 或 AzureFunctionsJobHost .
现在需要指出的有趣的事情是配置中没有任何地方提到 local.settings.json .那是因为 local.settings.json 不是 的一部分配置生成器 过程。而是 local.settings.json 是 Azure Functions Core Tools 的一部分,可让您在本地计算机 ( https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local ) 上开发和测试您的函数。 Azure 函数核心工具仅关注特定部分和键/值,例如 IsEncrypted , 值 和 连接字符串 文档中定义的部分等( https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local#local-settings-file )。这些键/值发生的事情也是独一无二的。例如, 中的键/值值 部分作为变量插入到环境中。大多数开发人员甚至没有注意到 local.settings.json 默认设置为被 Git 忽略,如果您从开发环境中删除存储库只是为了在将来恢复它,这也会导致问题。 ASP.NET Core 已使用应用程序 secret ( https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets ) 修复的问题。
那么,如果我们使用 创建我们自己的配置会发生什么?配置生成器 正如原始问题中所建议的
IConfiguration config = new ConfigurationBuilder()
.SetBasePath(context.FunctionAppDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
或使用其他答案之一中显示的示例?ExecutionContextOptions executionContextOptions = builder.Services.BuildServiceProvider().GetService<IOptions<ExecutionContextOptions>>().Value;
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
.SetBasePath(executionContextOptions.AppDirectory)
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json", false)
.AddJsonFile("local.settings.json", true)
.AddUserSecrets(Assembly.GetExecutingAssembly(), true);
以下只是这两个示例的一些问题。项目 list
builder.Services.AddSingleton<IConfiguration>(configurationBuilder.Build());
没有这一行,配置只存在于 配置(IFunctionsHostBuilder 构建器)您的方法 功能启动类(class)。但是,使用该行替换 Azure Function 内部构建的配置。这不一定是一件好事,因为您无法替换像 这样的提供商。 HostJsonFileConfigurationProvider .所有这些都为我们提供了一种更好的方法来影响对配置的更改,而不会破坏 Azure Function 的默认配置构建,即覆盖 配置应用配置 您的 中的方法功能启动类( https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#customizing-configuration-sources )。
以下示例通过添加用户 secret 使文档中提供的示例更进一步。
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
{
FunctionsHostBuilderContext context = builder.GetContext();
builder.ConfigurationBuilder
.SetBasePath(context.ApplicationRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
.AddJsonFile($"appsettings.{context.EnvironmentName}.json", optional: true, reloadOnChange: false)
.AddUserSecrets(Assembly.GetExecutingAssembly(), true, true)
.AddEnvironmentVariables();
}
默认情况下,配置文件如 appsettings.json 不会自动复制到 Azure Function 输出文件夹。请务必查看文档 ( https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#customizing-configuration-sources ) 以修改您的 .csproj 文件。另请注意,由于该方法附加现有提供程序的方式,必须始终以 结尾。 .AddEnvironmentVariables() .
关于azure - 在 FunctionsStartup 中使用 ConfigurationBuilder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57360238/