[英]Azure functions host.json somehow being ignored
我有一個 V2 Azure 功能。 我已將此函數配置為僅並行運行一個函數。 這是我的 host.json 文件:
{ "version": "2.0", "extensions": { "queues": { "batchSize": 1, "newBatchThreshold": 0 } } }
當我在本地開發機器上啟動該函數時,它顯示以下輸出:
[27-5-2019 12:43:06] 啟動 Rpc 初始化服務。
[27-5-2019 12:43:06] 初始化 RpcServer
[27-5-2019 12:43:06] 構建主機:啟動抑制:假,配置抑制:假
[27-5-2019 12:43:07] 初始化主機。
[27-5-2019 12:43:07] 主機初始化:ConsecutiveErrors=0,StartupCount=1
...
[27-5-2019 12:43:07] 隊列選項
[27-5-2019 12:43:07] {
[27-5-2019 12:43:07] "BatchSize": 16,
[27-5-2019 12:43:07] "NewBatchThreshold": 8,
[27-5-2019 12:43:07] "MaxPollingInterval": "00:00:02",
[27-5-2019 12:43:07] "MaxDequeueCount": 5,**
[27-5-2019 12:43:07] "VisibilityTimeout": "00:00:00"
在此輸出之后,似乎沒有注冊這些設置。 該行為也表明了這一點,因為該函數並行運行而不是一次運行一個。 我究竟做錯了什么?
任何幫助表示贊賞。
參考 MS host.json 規范
我遇到了與 Dave Parker 完全相同的問題,他對覆蓋 host.json 配置的新配置注冊的分析是正確的。
正如 jsgoupil 在 Dave 的帖子中評論的那樣, ImplementationInstance
是空的。 下面是對 Dave 代碼的一些輕微更新來處理這個問題。
public IConfigurationRoot AddSettings(IServiceCollection services, string basePath, string name, bool optional, bool reloadOnChange)
{
var builder = new ConfigurationBuilder().SetBasePath(basePath);
// check if an IConfiguration has already been registered
var existingConfig = builder.Services.FirstOrDefault(x => x.ServiceType.Name == nameof(IConfiguration));
if(existingConfig != null)
{
// get an instance of it and include it in the new config builder
var sp = builder.Services.BuildServiceProvider();
var existingInstance = sp.GetService<IConfiguration>();
builder.AddConfiguration(existingInstance);
}
// Register/load the requested json settings file
builder.AddJsonFile(name, optional, reloadOnChange);
// Add all environment vars and build the ConfigurationRoot object. Then register it with the services container
builder.AddEnvironmentVariables();
var config = builder.Build();
// Register the resulting IConfigurationRoot to as a singleton
services.AddSingleton<IConfiguration>(config);
return config;
}
我回應了 github 中報告的相同(或類似)問題。 為了幫助其他人登陸這里,我在這里重新發布。
為登陸這里的其他人添加更多信息。 另外,由於我沒有看到其他人提到這一點,我可能在解釋/做錯了。 如果是這樣,請說出來。
設想
[assembly: FunctionsStartup(typeof(Startup))]
new ConfigurationBuilder()
,添加我的配置內容IConfigurationRoot
注冊為單例IConfiguration
我觀察到的
在添加IConfigurationRoot
之前設置斷點並查看IServiceCollection
我可以看到已經注冊了一個單例IConfiguration
。 此外,此實例中包含 host.json 的提供程序,但在 Azure 中運行時並未加載。
我的理論
看起來,當注冊同一服務的兩個單例時,DI 框架只會獲取最后添加的一個。
我的解決方案
我從IServiceCollection
提取了現有的IConfiguration
提供程序並將其添加到ConfigurationBuilder
以便其值包含在我注冊的ConfigurationRoot
,從而被 DI 框架獲取。
代碼
public IConfigurationRoot AddSettings(IServiceCollection services, string basePath, string name, bool optional, bool reloadOnChange)
{
var builder = new ConfigurationBuilder().SetBasePath(basePath);
var existingConfigs = services.Where(svc => svc.ServiceType.Name == "IConfiguration").ToList();
foreach (var cfg in existingConfigs)
builder.AddConfiguration((IConfigurationRoot) cfg.ImplementationInstance);
// Register/load the requested json settings file
builder.AddJsonFile(name, optional, reloadOnChange);
// Add all environment vars and build the ConfigurationRoot object. Then register it with the services container
builder.AddEnvironmentVariables();
var config = builder.Build();
// Register the resulting IConfigurationRoot to as a singleton
services.AddSingleton<IConfiguration>(config);
return config;
}
我希望這對某人有幫助
非常感謝你做的這些! 我使用了一個小的變化,因為我在啟動期間利用工廠模式的延遲調用來引用配置:
public static IServiceCollection AddConfigurationFactory(this IServiceCollection services)
{
var configurationEnvironment = Environment.GetEnvironmentVariable("ConfigEnv");
var jsonConfigFilename = $"appsettings.{configurationEnvironment}.json";
#if DEBUG
var basePath = Environment.CurrentDirectory;
#else
var basePath = @"/home/site/wwwroot";
#endif
var existingConfig = services.FirstOrDefault(x => x.ServiceType.Name ==
nameof(IConfiguration));
IConfiguration existingInstance = null;
if (existingConfig != null)
{
var spOuter = services.BuildServiceProvider();
existingInstance = spOuter.GetService<IConfiguration>();
}
Func<IServiceProvider, IConfiguration> factory = (sp) =>
{
var configBuilder = new ConfigurationBuilder()
.SetBasePath(basePath)
.AddEnvironmentVariables()
.AddJsonFile(jsonConfigFilename, optional: false, reloadOnChange: true);
if (existingInstance != null)
configBuilder.AddConfiguration(existingInstance);
return configBuilder.Build();
};
services.AddSingleton<IConfiguration>(factory);
return services;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.