我具有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] QueuesOptions
[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 specification
的引用答案 0 :(得分:5)
我遇到了与Dave Parker完全相同的问题,他发现了对新配置注册覆盖host.json配置的分析。
正如jsgoupil在Dave的帖子中所述,ImplementationInstance
为null。这是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;
}
答案 1 :(得分:3)
似乎报告了here个未解决的问题,函数启动忽略了host.json
如果您的代码中包含[assembly: WebJobsStartup(typeof(Startup))]
,请删除应该正确识别的host.json
。
答案 2 :(得分:2)
I responded与github中报告的相同(或相似)问题有关。为了帮助其他人降落在这里,我在这里重新发布。
为落在此处的其他人添加更多信息。另外,由于我还没有看到其他人提到此内容,因此我可能在解释/做错了此事。如果是这样,请说出来。
场景
[assembly: FunctionsStartup(typeof(Startup))]
new ConfigurationBuilder()
,添加我的配置资料IConfigurationRoot
注册为单例IConfiguration
我观察到的情况
在添加我的IConfigurationRoot
并查看IServiceCollection
之前设置一个断点,我可以看到已经注册了一个单例IConfiguration
。此外,此实例中包含host.json的提供程序,但在Azure中运行时未加载该文件。
我的理论
似乎在注册同一服务的两个单例时,DI框架将仅获取最后添加的一个。
我的解决方案
我从IConfiguration
中提取了现有的IServiceCollection
提供者,并将其添加到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;
}
我希望这对某人有帮助
答案 3 :(得分:0)
非常感谢您!我使用了一个小的变化,因为我在启动期间利用工厂模式的延迟调用来引用配置:
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;
}