1

I'm having a little issue with my code.

Basically, I'm trying to dynamically add classes that I've created from deserializing JSON into my ServiceCollection, so I can get them from any class that needs them. So far I've got the following code:

Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsSubclassOf(typeof(AbstractConfiguration)) && !t.IsAbstract).ToList().ForEach(x => {
    if (!File.Exists(x.Name + ".json")) {
        object Configuration = Activator.CreateInstance(x);
        File.WriteAllText(x.Name + ".json", JsonSerializer.Serialize(Configuration, new JsonSerializerOptions() { WriteIndented = true }));
        ServiceCollection.AddSingleton(Configuration);
     } else {
        string json = File.ReadAllText(x.Name + ".json");
        object Configuration = JsonSerializer.Deserialize(json, x, new JsonSerializerOptions() { WriteIndented = true });
        ServiceCollection.AddSingleton(Configuration);
    }
});

We load up our JSON into a class (which works), add it into our collection (which works), however; when adding into our collection the type is an object, so when I try call it through Services.GetServices(typeof(BotConfiguration)).ToList().Count);, it returns 0. What gives?

Well, if we instead try run Services.GetServices(typeof(object)).ToList().ForEach(x => Console.WriteLine(x.ToString()));, we can actually see that this instantiation actually falls under the object type, even though when we run x.ToString(), it shows that it is an instance of BotConfiguration (outputs Dexter.Core.Configurations.BotConfiguration in my case).

How would we get our ServiceCollection to add this as its actual class rather than an object? It clearly knows what type it is...?

FeroxFoxxo
  • 576
  • 1
  • 5
  • 18
  • This sounds awfully similar to using `IOptions` with JSON files: https://stackoverflow.com/q/49046847/5803406 – devNull Aug 24 '20 at 00:56
  • I was going to go with IOptions but looking over the code for it gave me a bit of a headache lmao, so I decided to go with (what was in my opinion) as simpler solution - which worked until I moved most of my project over to being instanced by Microsoft's dependency injection, as the main library I used requried it. – FeroxFoxxo Aug 24 '20 at 01:16

1 Answers1

1

You code is calling generic version of method (AddSingleton<TService>(IServiceCollection, TService)) with generic type parameter being resolved at compile time to object, try calling one accepting Type parameter (see all overloads) like this:

ServiceCollection.AddSingleton(x);

UPD

There is overload (AddSingleton(IServiceCollection, Type, Object)) accepting type and object instance:

ServiceCollection.AddSingleton(x, Configuration);
Guru Stron
  • 102,774
  • 10
  • 95
  • 132