0

I have followed this post to create a writable options class for .Net Core WebAPI. I use this class for updating my appsettings.json file.

I want to create these writable options classes dynamically. For example, I have multiple options classes like OptionsA, OptionsB and so on. They can be configured in appsettings.json and should only be injected when they are present in that file.

So far so good, now my problem is ConfigureWritable has a type parameter T. My problem is, when my code finds OptionsA in the appsettings.json file, how do I supply the type to the ConfigureWritable method?

Here's what I have so far:

private void AddOptionalServices(IServiceCollection services, ServiceSettings serviceSettings)
{
    foreach (var serviceSetting in serviceSettings.Services)
    {
        var serviceType = AppDomain.CurrentDomain.GetAssemblies().SelectMany(t => t.GetTypes()).Where(t => t.Name == serviceSetting.Name).FirstOrDefault();
        var settingsType = (Type)serviceType.GetProperty("ServiceType").GetValue(serviceType, null);


        services.AddSingleton(typeof(IHostedService), serviceType);
        services.ConfigureWritable<settingsType>(Configuration.GetSection("")); //Problem lies here
    }
}

settingsType is a property that is returned from serviceType.

EDIT: Second attempt based on Lasse's comment:

private void AddOptionalServices(IServiceCollection services, ServiceSettings serviceSettings)
{
    foreach (var serviceSetting in serviceSettings.Services)
    {
        var serviceType = AppDomain.CurrentDomain.GetAssemblies().SelectMany(t => t.GetTypes()).Where(t => t.Name == serviceSetting.Name).FirstOrDefault();
        var settingsType = (Type)serviceType.GetProperty("ServiceType").GetValue(serviceType, null);

        services.AddSingleton(typeof(IHostedService), serviceType);
        var method = typeof(IServiceCollection).GetMethod("ConfigureWritable"); //returns null
        var methods = typeof(IServiceCollection).GetMethods(); //returns empty enumeration
        var generic = method.MakeGenericMethod(settingsType);
        generic.Invoke(this, null);
    }
}

As you can see, I don't get the method back when using GetMethod.

LeonidasFett
  • 3,052
  • 4
  • 46
  • 76
  • 1
    You need to use reflection. Use `MakeGenericMethod` on a `MethodInfo` to inject the type as an argument, then use `.Invoke` to call it. Or, you can use a switch-statement on the strings to have specific code, if the list of types is small and relatively fixed. – Lasse V. Karlsen Jun 14 '18 at 11:45
  • I have tried following this post: https://stackoverflow.com/questions/232535/how-do-i-use-reflection-to-call-a-generic-method but I get a NullReferenceException when trying to get the method ConfigureWritable from IServiceCollection. I think this is because ConfigureWritable is a extension method. – LeonidasFett Jun 14 '18 at 11:56
  • 1
    You have to get the method from where it is definied. – thehennyy Jun 14 '18 at 12:21
  • I tried substituting IServiceCollection for the actual class which contains the extension method and voila, it was found! Dummy me! thanks for the hint :) – LeonidasFett Jun 14 '18 at 12:30
  • If you want you can put it as an answer, I will accept it afterwards. – LeonidasFett Jun 14 '18 at 12:30
  • Busy for quite some time today, someone will take the ball and run with it and produce an answer for you. Or, you can write up an answer yourself if you want. – Lasse V. Karlsen Jun 14 '18 at 12:46

0 Answers0