Search code examples
c#asp.netasp.net-coredependency-injection

How to inject IOptionsMonitor in the service in ASP.NET Core 7?


I've create an options class:

public class OktaOptions
    {
        public const string Okta = "Okta";

        public string OktaDomain = string.Empty;
        public string AuthorizationServerId = string.Empty;
        public string Audience = string.Empty;
        public string ClientId = string.Empty;
        public string ClientSecret = string.Empty;
        public string Scopes = string.Empty;
    }

Then I registered it in the separate extensions class

public static IServiceCollection AddConfigurationOptions(this IServiceCollection services, IConfiguration configuration)
     {
         services.Configure<OktaOptions>(
         configuration.GetSection("Okta"));
        
         return services;
     }

Then I registered this class method in the program.cs like this

builder.Services.AddConfigurationOptions(builder.Configuration);

I want to use this IOptionMonitor in another service extension method (in the authorization service extension), I am trying to inject my IOptionMonitor as the parameter

public static IServiceCollection AddAuthenticationService(this IServiceCollection services, IOptionsMonitor<OktaOptions> oktaOptions)
        {
            services.AddAuthentication(options =>
                {
                    //logic here
                })
                .AddOktaWebApi(new OktaWebApiOptions()
                {
                    OktaDomain = oktaOptions.CurrentValue.OktaDomain,
                    AuthorizationServerId = oktaOptions.CurrentValue.AuthorizationServerId,
                    Audience = oktaOptions.CurrentValue.Audience
                });

            return services;
        }

Program.cs class

builder.Services.AddAuthenticationService(IOptionsMonitor<OktaOptions> oktaOptions);

But it doesn't work and IntelliSense tells me that "IOptionsMonitor is a type which is not valid in the given context interface name is not valid at this point" What can I do to fix this problem?


Solution

  • There is no reason to use IOptionsMonitor here, it will have no effect, the values will be read one time by AddOktaWebApi and that's it, just use OktaOptions or OktaWebApiOptions. For example read them from config:

    public static IServiceCollection AddAuthenticationService(this IServiceCollection services, IConfiguration configuration)
    {
        var opts = configuration.GetSection("Okta").Get<OktaWebApiOptions>();
        services.AddAuthentication(options =>
            {
                //logic here
            })
            .AddOktaWebApi(opts);
    
        return services;
    }
    
    builder.Services.AddAuthenticationService(builder.Configuration);
    

    Or

    static IServiceCollection AddAuthenticationService(this IServiceCollection services, OktaOptions oktaOptions)
    {
        services.AddAuthentication(options =>
            {
                //logic here
            })
            .AddOktaWebApi(new OktaWebApiOptions()
            {
                OktaDomain = oktaOptions.OktaDomain,
                AuthorizationServerId = oktaOptions.AuthorizationServerId,
                Audience = oktaOptions.Audience
            });
    
        return services;
    }
    
    var oktaOptions = builder.Configuration.GetSection("Okta").Get<OktaOptions>();
    builder.Services.AddAuthenticationService(oktaOptions);