[英]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.