Click here to Skip to main content
15,867,686 members
Articles / Programming Languages / C#
Tip/Trick

Workaround for ServiceCollection.Configure<T> failing where T is ConcurrentDictionary<string, TMyConfig> in NET7

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
29 Nov 2022CPOL 10.7K   1   3
Option Binding for a ConcurrentDictionary that works in NET6 fails in NET7. This is a workaround.
Workaround for a regression in NET7 discovered while converting a project from NET6 to NET7.

Description

I have an ModuleCollection class which is:

C#
/// <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:

C#
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. 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:

C#
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 ModuleConfigs.

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) CodeProject
Canada Canada
As Senior Architect, Matthew is responsible for the Architecture, Design, and Coding of the CodeProject software as well as Manager of the Infrastructure that runs the web site.

Matthew works on improving the performance and experience of the Code Project site for users, clients, and administrators.

Matthew has more years of software development, QA and architecture experience under his belt than he likes to admit. He graduated from the University of Waterloo with a B.Sc. in Electrical Engineering. He started out developing micro-processor based hardware and software including compilers and operating systems.
His current focus is on .NET web development including jQuery, Webforms, MVC, AJAX, and patterns and practices for creating better websites.
He is the author of the Munq IOC, the fastest ASP.NET focused IOC Container.
His non-programming passions include golf, pool, curling, reading and building stuff for the house.

Comments and Discussions

 
PraiseThank you Pin
Dirk_Strauss7-Dec-22 22:33
professionalDirk_Strauss7-Dec-22 22:33 
Well done on providing a workaround for this. Thank you!

GeneralGitHub bug report Pin
Richard Deeming29-Nov-22 22:54
mveRichard Deeming29-Nov-22 22:54 
GeneralRe: GitHub bug report Pin
Matthew Dennis30-Nov-22 3:56
sysadminMatthew Dennis30-Nov-22 3:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.