How to resolve IOptions instance inside ConfigureServices?

Is it possible to resolve an instance of IOptions<AppSettings> from the ConfigureServices method in Startup? The documentation explicitly says:

Don't use IOptions<TOptions> or IOptionsMonitor<TOptions> in Startup.ConfigureServices. An inconsistent options state may exist due to the ordering of service registrations.

You can manually create a service provider using serviceCollection.BuildServiceProvider() but this results in the warning:

Calling 'BuildServiceProvider' from application code results in an additional copy of singleton services being created. Consider alternatives such as dependency injecting services as parameters to 'Configure'.

How can I achieve this?

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<AppSettings>(
        configuration.GetConfigurationSection(nameof(AppSettings)));

    // How can I resolve IOptions<AppSettings> here?
}

If you need to resolve service using the service provider manually you can use this AddSingleton/AddScoped/AddTransient overload:

// Works for AddScoped and AddTransient as well
services.AddSingleton<IBarService>(sp =>
{
    var fooService = sp.GetRequiredService<IFooService>();
    return new BarService(fooService);
}

If you really want to, you can build an intermediate service provider using the BuildServiceProvider() method on the IServiceCollection:

public void ConfigureService(IServiceCollection services)
{
    // Configure the services
    services.AddTransient<IFooService, FooServiceImpl>();
    services.Configure<AppSettings>(configuration.GetSection(nameof(AppSettings)));

    // Build an intermediate service provider
    var sp = services.BuildServiceProvider();

    // Resolve the services from the service provider
    var fooService = sp.GetService<IFooService>();
    var options = sp.GetService<IOptions<AppSettings>>();
}

You need the Microsoft.Extensions.DependencyInjection package for this.

However, please note that this results in multiple service provider instances which may in turn result in multiple singleton instances.


In the case where you just need to bind some options in ConfigureServices, you can also use the Bind method:

var appSettings = new AppSettings();
configuration.GetSection(nameof(AppSettings)).Bind(appSettings);

This functionality is available through the Microsoft.Extensions.Configuration.Binder package.


The best way for instantiating classes that are dependent on other services is to use the AddXXX overload that provides you with the IServiceProvider. This way you do not need to instantiate an intermediate service provider.

The following samples show how you can use this overload in AddSingleton/AddTransient methods.

services.AddSingleton(serviceProvider =>
{
    var options = serviceProvider.GetService<IOptions<AppSettings>>();
    var foo = new Foo(options);
    return foo ;
});


services.AddTransient(serviceProvider =>
{
    var options = serviceProvider.GetService<IOptions<AppSettings>>();
    var bar = new Bar(options);
    return bar;
});