Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

431
Views
How can I dynamically re-configure a Service during runtime in ASP.NET Core 5?

I am using Google authentication in my web app, and the OAuth keys are currently hard-coded in ConfigureServices:

services.AddAuthentication()
    .AddGoogle(options =>
    {
        options.ClientId = "my-client-id";
        options.ClientSecret = "my-client-secret";
    });

However, I would like to give the site administrator the opportunity to change the ClientId and ClientSecret from the web app's settings page, preferably without having to restart the server.

To do this, I'd have to somehow trigger a re-configuration of the Google service and the GoogleOptions object when the user hits 'Save' on the settings page. This is what I'm having trouble with. Also, I would like to store these settings in an EF Core DbContext, and not in a physical config file.

So far I've tried to move the settings to a separate class that implements IPostConfigureOptions. This should allow me to inject my database context, because based on the documentation, PostConfigure is supposed to run after all other configurations have occurred. The settings are loaded correctly from this new class, but the injection of the DB context fails with the following exception:

System.InvalidOperationException: Cannot consume scoped service 'AppDatabase' from singleton 'IOptionsMonitor`1[GoogleOptions]'

This is weird, because the ConfigureGoogleOptions is registered as Scoped, and not as a Singleton.

Here's my options class:

public class ConfigureGoogleOptions : IPostConfigureOptions<GoogleOptions>
{
    private readonly AppDatabase database;

    public ConfigureGoogleOptions(AppDatabase database)
    {
        this.database = database;
    }
    
    public void PostConfigure(string name, GoogleOptions options)
    {
        options.ClientId = "my-client-id.apps.googleusercontent.com";
        options.ClientSecret = "my-client-secret";
    }
}

And registering it in ConfigureServices:

services.AddScoped<IPostConfigureOptions<GoogleOptions>, ConfigureGoogleOptions>();

Even if the databse injection worked, there's still a second problem. The PostConfigure function in my class only gets called once after the application starts, and never again. I assume that it caches the settings somewhere, and I don't know how to invalidate or disable this cache so I can dynamically provide values.

Short Summary / tl;dr:

I want to load the ClientId and ClientSecret settings of the Google OAuth service from my own database, and I want to be able to change them dynamically while the server is running.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Internally the google handler will use IOptionsMonitor<GoogleOptions> to get the GoogleOptions once or until it's reloaded (such as when the options is bound from a configuration file and saving the file will trigger the reloading). The IOptionsMonitor internally will use IOptionsMonitorCache and this cache is registered as singleton. So the options instance you get from IOptionsMonitor<GoogleOptions> is the same (reference) with the AuthenticationHandler<GoogleOptions>.Options which is used for various operations inside the handler. Even other code if using that options should correctly get it from IOptionsMonitor<GoogleOptions>.

So to change the options at runtime, it's just simple like this:

//inject the IOptionsMonitor<GoogleOptions> into _googleOptionsMonitor;
var runtimeOptions = _googleOptionsMonitor.Get(GoogleDefaults.AuthenticationScheme);
//you change properties of runtimeOptions here
//...

The important point here is we need to use GoogleDefaults.AuthenticationScheme as the key to get the correct instance of options. The IOptionsMonitor.CurrentValue will use the default key of Options.DefaultName (which is an empty string).

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!