Repository navigation
ServiceCollection.Configure<ConcurrentDictionary<string, T>>(IConfigurationSection) fails in NET7 #78994
Copy link
Copy link
Closed
Labels
area-Extensions-Optionsneeds-author-actionAn issue or pull request that requires more info or actions from the author.An issue or pull request that requires more info or actions from the author.
Milestone
Description
Description
I have an ModuleCollection class which is
/// <summary>
/// The set of modules for backend processing.
/// </summary>
public class ModuleCollection : ConcurrentDictionary<string, ModuleConfig>
{
/// <summary>
/// This constructor allows our modules collection to be case insensitive on the key.
/// </summary>
public ModuleCollection() : base(StringComparer.OrdinalIgnoreCase) { }
}In NET6
services.Configure<ModuleCollection>(configuration.GetSection("Modules"));would load the ModuleCollection with the ModuleConfigs from multiple modulesettings.json files that had been registered with the ConfigurationBuilder. TheIOption<ModuleCollection>injected would have the populated collection as its value.
In NET7 the IOption<ModuleCollection>.Value is an empty ModuleCollection
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);
}
}
});Reproduction Steps
see above
Expected behavior
Same as NET6
IOption<ModuleCollection>.Value contains the collection of ModuleConfigs/
Actual behavior
The IOption<ModuleCollection>.Value is an empty collection.
Regression?
It worked on NET6
Known Workarounds
ModuleCollection moduleCollection = new();
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);
}
}
});Configuration
NET7, VS2022 17.4.1
Other information
I can bind to a single ModuleConfig, just the binding to the dictionary is failing, so it is probably in the Dictionary Binder in NET7.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area-Extensions-Optionsneeds-author-actionAn issue or pull request that requires more info or actions from the author.An issue or pull request that requires more info or actions from the author.
Activity
matthewDDennis commentedon Nov 29, 2022
Probably should be labeled area-Extensions-Options
[-]ServiceCollection.Configure<Dictionary<string, T>>(IConfigurationSection) fails in NET7[/-][+]ServiceCollection.Configure<ConcurrentDictionary<string, T>>(IConfigurationSection) fails in NET7[/+]RichardD2 commentedon Nov 30, 2022
Do you actually need the
ModuleCollection moduleCollection = new();line? That variable doesn't seem to be used anywhere else - the other references use the lambda method parameter with the same name.matthewDDennis commentedon Nov 30, 2022
You are correct. That was a copy & paste error from my test code to determine what was broken.
I've updated my question.
Thanks.
tarekgh commentedon Nov 30, 2022
@matthewDDennis could you please try to run using
Microsoft.Extensions.*packages from the nuget private feedand use the version:
8.0.0-alpha.1.22578.1I am asking because this look it is already fixed by #78118.
If it is still reproduced, please provide a small app that reproduces the problem we can try. Thanks.
matthewDDennis commentedon Nov 30, 2022
I am not able to do that at the moment as I am working on the migration from net6 to net7.
I still have some work to go before I will be able to branch and check that out.
I see you have back ported the fix to 7.0.1.
Is that available in the standard NuGet feed yet?
However, the description on #78118 looks exactly like what I am seeing.
Once I get to a good point I will check it out, preferably with 7.0.1.
tarekgh commentedon Dec 1, 2022
Either you can wait for .NET 7.0.1 release, or you try what I mentioned in the comment #78994 (comment) or download the file https://dotnetbuilds.azureedge.net/public/aspnetcore/Runtime/7.0.1-servicing.22565.7/aspnetcore-runtime-7.0.1-win-x64.zip and copy the assembly
Microsoft.Extensions.Configuration.Binder.dllto yourdotnet\shared\Microsoft.AspNetCore.App\7.0.0folder. Make sure to back up the original file before overwriting it so you may copy it back.tarekgh commentedon Jan 5, 2023
I have confirmed this issue is fixed in
7.0.1. I used the following code. I can see the issue repro on7.0.0.repro code
appsettings.json
{ "Modules": { "module1": "moduleConfig1", "module2": "moduleConfig2", "module3": "moduleConfig3" } }