Pau*_*els 7 azure azure-functions
我有一个 Azure 函数,我正在使用 DI 系统来注册一些类型;例如:
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services
.AddTransient<IMyInterface, MyClass>()
. . . etc
Run Code Online (Sandbox Code Playgroud)
但是,我还要从我的环境设置中注册一些数据。在函数本身内部,我可以获得ExecutionContext
, 所以我可以这样做:
IConfiguration config = new ConfigurationBuilder()
.SetBasePath(context.FunctionAppDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
Run Code Online (Sandbox Code Playgroud)
但是,在 FunctionsStartup 中,我无权访问ExecutionContext
. 有没有一种方法可以从 FunctionsStartup 类中获取 ExecutionContext ,或者另一种确定当前运行目录的方法,以便我可以设置基本路径?
Ter*_*lla 17
虽然对这个问题的检查答案是正确的,但我认为它缺乏关于原因的深度。您应该知道的第一件事是,在幕后,Azure 函数使用与ASP.NET Core 应用程序中相同的ConfigurationBuilder,但具有不同的提供程序集。与 ASP.NET Core 的文档(https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/)不同,Azure Functions 并非如此。
要了解这组提供程序,您可以将以下代码行放入FunctionStartup类的Configure(IFunctionsHostBuilder builder)方法中,
var configuration = builder.Services.BuildServiceProvider().GetService<IConfiguration>();
Run Code Online (Sandbox Code Playgroud)
在命令后放置一个调试断点,在调试模式下执行您的函数并在配置变量上执行快速观察...(右键单击变量名称以选择快速观察...)。
深入代码执行的结果是以下提供程序列表。
Microsoft.Extensions.Configuration.ChainedConfigurationProvider
MemoryConfigurationProvider
HostJsonFileConfigurationProvider
JsonConfigurationProvider for 'appsettings.json' (Optional)
EnvironmentVariablesConfigurationProvider
MemoryConfigurationProvider
Run Code Online (Sandbox Code Playgroud)
所述ChainedConfigurationProvider增加了一个现有IConfiguration作为源。在默认配置情况下,添加主机配置并将其设置为应用程序配置的第一个源。
第一个MemoryConfigurationProvider添加键/值{[AzureWebJobsConfigurationSection, AzureFunctionsJobHost]}。至少它在开发环境中是这样做的。在我写这篇文章的时候,我找不到关于这个MemoryConfigurationProvider或AzureWebJobsConfigurationSection目的的文档。
该HostJsonFileConfigurationProvider是那些在幕后无证供应商的另外一个,但是在看的文件host.json(https://docs.microsoft.com/en-us/azure/azure-functions/functions-host-json)它似乎负责提取此元数据。
该JsonConfigurationProvider为appsettings.json似乎是一个明显的相关性,以ASP.NET核心的使用appsettings.json除了一件事是这是行不通的。经过一番调查,我发现Source FileProvider Root没有设置为文件所在的应用程序根文件夹,而是一些模糊的 AppData 文件夹(C:\Users%USERNANE%\AppData\Local\AzureFunctionsTools\Releases\3.15.0\ cli_x64)。 去钓鱼。
该EnvironmentVariablesConfigurationProvider负载环境变量的键值对。
第二个MemoryConfigurationProvider添加键/值{[AzureFunctionsJobHost:logging:console:isEnabled, false]}。至少它在开发环境中是这样做的。同样,在我写这篇文章的时候,我找不到关于这个MemoryConfigurationProvider或AzureFunctionsJobHost目的的文档。
现在需要指出的有趣的事情是配置中没有任何地方提到local.settings.json。那是因为local.settings.json不是ConfigurationBuilder进程的一部分。而local.settings.json是 Azure Functions Core Tools 的一部分,它允许您在本地计算机上开发和测试您的函数 ( https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-本地)。Azure 函数核心工具仅关注文档中定义的特定部分和键/值,如IsEncrypted、Values和ConnectionString部分等(https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local#local-settings-file)。这些键/值发生的事情也是独一无二的。例如,值部分中的键/值作为变量插入到环境中。大多数开发人员甚至没有注意到 local.settings.json 默认设置为被 Git 忽略,如果您从开发环境中删除存储库只是为了在将来恢复它,这也会导致问题。ASP.NET Core 已使用应用程序机密 ( https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets )修复的某些内容。
那么,如果我们按照原始问题中的建议使用ConfigurationBuilder创建我们自己的配置会发生什么
IConfiguration config = new ConfigurationBuilder()
.SetBasePath(context.FunctionAppDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
Run Code Online (Sandbox Code Playgroud)
或使用其他答案之一中显示的示例?
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);
Run Code Online (Sandbox Code Playgroud)
以下只是这两个示例的一些问题。
第二个示例的顺序不正确,因为 AddEnvironmentVariables 应该放在最后。
这两个示例都没有提到需要以下代码行。项目清单
builder.Services.AddSingleton<IConfiguration>(configurationBuilder.Build());
如果没有这一行,则配置仅存在于FunctionStartup类的Configure(IFunctionsHostBuilder builder)方法中。但是,使用该行替换 Azure Function 内部构建的配置。这不一定是一件好事,因为您无法替换HostJsonFileConfigurationProvider 之类的提供程序。
读取local.settings.json文件(.AddJsonFile("appsettings.json"))不会像预期的那样将Values部分中的键/值对作为单独的键/值对放入配置中,而是将它们分组在Values 下部分。换句话说,例如,如果你想获得{[“AzureWebJobsStorage”:“”]}的值,你可以使用命令configuration.GetValue(“值:AzureWebJobsStorage”) 。问题是 Azure 期望通过键名"AzureWebJobsStorage"访问它。更有趣的是,因为local.settings。这是多余的,因为 Azure Functions Core Tools 已经将这些值放入环境中。这将做的唯一一件事是允许您访问未定义为local.settings.json ( https://docs.microsoft.com/en-us/azure/azure-functions/functions-run -local#local-settings-file)。但是为什么要从不会复制到生产代码中的文件中提取配置值呢?
所有这些都为我们提供了一种更好的方法来影响对配置的更改,而不会破坏 Azure Function 的默认配置构建,即覆盖FunctionStartup类中的ConfigureAppConfiguration方法( https://docs.microsoft.com/en-us/ azure/azure-functions/functions-dotnet-dependency-injection#customizing-configuration-sources)。
以下示例通过添加用户机密使文档中提供的示例更进一步。
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();
}
Run Code Online (Sandbox Code Playgroud)
默认情况下,appsettings.json等配置文件不会自动复制到 Azure Function 输出文件夹。请务必查看文档 ( https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#customizing-configuration-sources ) 以了解对.csproj文件的修改。另请注意,由于该方法附加现有提供程序的方式,必须始终以.AddEnvironmentVariables()结尾。
Azure Functions (v2) 中不需要任何配置对象。所有应用程序设置都作为环境变量注入。所以你可以做一个简单的Environment.GetEnvironmentVariable()
在本地运行时local.settings.json
,以相同的方式读取。
请参阅此处:https : //docs.microsoft.com/en-us/sandbox/functions-recipes/environment-variables?tabs=csharp
归档时间: |
|
查看次数: |
5041 次 |
最近记录: |