Skip to content

ServiceCollection.Configure<ConcurrentDictionary<string, T>>(IConfigurationSection) fails in NET7 #78994

Description

@matthewDDennis

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions