Workaround for a regression in NET7 discovered while converting a project from NET6 to NET7.
Description
I have an ModuleCollection
class which is:
public class ModuleCollection : ConcurrentDictionary<string, ModuleConfig>
{
public ModuleCollection() : base(StringComparer.OrdinalIgnoreCase) { }
}
In NET6:
services.Configure<ModuleCollection>(configuration.GetSection("Modules"));
would load the ModuleCollection
with the ModuleConfig
s from multiple modulesettings.json files that had been registered with the ConfigurationBuilder
. The IOption<ModuleCollection>
injected would have the populated collection as its value.
In NET7, the IOption<ModuleCollection>.Value
is an empty ModuleCollection
.
Workaround
I worked around this by:
services.AddOptions<ModuleCollection>()
.Configure(moduleCollection =>
{
var moduleNames = configuration.GetSection("Modules").GetChildren().Select(x => x.Key).ToList();
foreach (var moduleName in moduleNames)
{
if (moduleName is not null)
{
ModuleConfig moduleConfig = new ModuleConfig();
configuration.Bind($"Modules:{moduleName}", moduleConfig);
moduleCollection.TryAdd(moduleName, moduleConfig);
}
}
});
Expected Behavior
Same as NET6
IOption<ModuleCollection>.Value
contains the collection of ModuleConfig
s.
Actual Behavior
The IOption<ModuleCollection>.Value
is an empty collection.
Issue Tracking
This issue is being tracked in
ServiceCollection.Configure<ConcurrentDictionary<string, T>>(IConfigurationSection) fails in NET7 · Issue #78994 · dotnet/runtime · GitHub[^],
Configuration
NET7, VS2022 17.4.1
History
- 29th November, 2022: Initial version