Getting IConfiguration from ServiceCollection

I created my own "service collection" type which wrapped the IServiceCollection and IConfiguration and all my modules use that type to register their services. For example:

public interface IMyServiceCollection
{
    public IServiceCollection Services { get; set; }

    public IConfiguration Configuration { get; set; }
}

public static void AddFooModule(this IMyServiceCollection myServices)
{
    var services = myServices.Services;
    var config = myServices.Configuration;
}

Then you have to create an extension method with the configuration instance as parameter which creates the implementation for IMyServiceCollection, such as:

public static IMyServiceCollection CreateServiceCollection(this IServiceCollection services, IConfiguration config)
{
    return new MyServiceCollection 
    { 
        Services = services,
        Configuration = config
    };
}

Note that we are using this in a modular framework. For simple applications this is overkill.

I think that your solution is fine as well. But if you need access to the IConfiguration instance frequently you might find searching for it in the service collection over and over a bit tedious.


To get IConfiguration from IServiceCollection why not just resolve the dependency?:

IConfiguration configuration = services.BuildServiceProvider().GetService<IConfiguration>();

According to the comments I have changed my extension method to the following, so that it is up to the composer of the application to provide the config section for my options.

public static IServiceCollection AddApi(this IServiceCollection services, IConfiguration databaseConfiguration)
{  
  services.Configure<DatabaseOptions>(databaseConfiguration);
}

from the StartUp class, the call looks like

public void ConfigureServices(IServiceCollection services)
{
  services.AddApi(Configuration.GetSection("Database"));
  services.AddMvc();
}

The decision to use it this way are mostly by these comments. This way maybe more relevant, when developing components that are use by many developers than for an internal component you use in your application.

Imho it's a bad design to access IConfiguration from anywhere except inside the composition root (Startup class for ASP.NET core), as this implies that the configuration file must have a specific structure which can't be changed at all. Instead, I'd write an extension method to configure the config classes inside the composition root and pass a IConfiguration object to, similar to how .Configure(Configuration.GetSection("MyLibConfi‌​g"). This way the developer who composes his application from your components can decide where to place it within the appsettings.json

Or how would you solve conflicts, when two libraries directly reference the IConfiguration and have the same section within the config? i.e. JsonSettings but have completely different structure? It can only be solved by letting the developer who compose it choose and pass the section name to the your extension method which sets up the options via .Configure