Search code examples
c#asp.netasp.net-corecontainersinversion-of-control

How to append in already created service/bean (Dict<string, List<SomeInterface>) in IOC container in dot net?


I'm working on a .NET project and adding a Dictionary<string, > to the container. Using the statement below works fine.

However, I need to initially add a few classes to this dictionary and then add more later. I'm trying to use GetService<Dictionary<string, List>> to append additional classes, but it's not working. Please help me find the correct way to append more entries to it.

 builder.Services.AddScoped(sp =>
 {
     var options = sp.GetService<IOptionsMonitor<CommonOption>>().CurrentValue;
     var demoOptions = new Dictionary<string, List<SomeInterface>>();

     foreach (var kvp in options)
     {
         if(kvp.Key != "X")
         {
             continue;
         }
         var demoList = kvp.Value.Select(item => SomeMethod(item)).ToList();
         demoOptions .Add(kvp.Key, demoList);
     }
     return demoOptions;
 });

Now I want to append more classes in above dictinary where kvp.Key != "X". Above code in some other service so can't use if else.


Solution

  • Use singleton service as a sample.

    Program.cs

    builder.Services.Configure<CommonOption>(builder.Configuration.GetSection("CommonOption"));
    
    builder.Services.AddSingleton(sp =>
    {
        var options = sp.GetService<IOptionsMonitor<CommonOption>>().CurrentValue.Options;
        var demoOptions = new Dictionary<string, List<TestInterface>>();
    
        foreach (var kvp in options)
        {
            if (kvp.Key == "X")
            {
                var demoList = kvp.Value.Select(item => TestMethodUtility.TestMethod(item)).ToList();
                demoOptions.Add(kvp.Key, demoList);
            }
        }
        return demoOptions;
    });
    
    builder.Services.AddScoped<DictionaryUpdateService>();
    builder.Services.AddScoped<SomeOtherService>();
    

    TestClass.cs

    public class TestClass : TestInterface
    {
        public string Name { get; set; } = "DefaultName";
    }
    

    TestInterface.cs

    public interface TestInterface
    {
        string Name { get; set; } 
    }
    

    TestMethod.cs

    public static class TestMethodUtility
    {
        public static TestInterface TestMethod(string input)
        {
            return new TestClass { Name = input };
        }
    }
    

    DistionaryUpdateService.cs

    public class DictionaryUpdateService
    {
        private readonly Dictionary<string, List<TestInterface>> _options;
    
        public DictionaryUpdateService(Dictionary<string, List<TestInterface>> options)
        {
            _options = options;
        }
    
        public void AppendEntries(IDictionary<string, List<TestInterface>> newEntries)
        {
            foreach (var kvp in newEntries)
            {
                if (_options.ContainsKey(kvp.Key))
                {
                    _options[kvp.Key].AddRange(kvp.Value);
                }
                else
                {
                    _options[kvp.Key] = new List<TestInterface>(kvp.Value);
                }
            }
        }
    }
    

    enter image description here enter image description here