avechuche
avechuche

Reputation: 1560

AddSingleton - Create on run application

I need to create singletons when the application starts. In this example, I create an instance of IdentityOptions with new values. The problem is that when I start the application and I want to create a new user, it is not taking the value 125 (it keeps using 6, which is the default), but if I modify that value from a controller (see example), everything works perfectly. I understand that the instance is created at the first request, but is it possible to create it when starting the application? Because my idea is to load those values from a database.

Startup.cs

public void ConfigureServices(IServiceCollection serviceCollection)
{
    ...
    ...
    ...

    serviceCollection.AddIdentity<ApplicationUser, ApplicationRole>()
        .AddEntityFrameworkStores<DatabaseContext>()
        .AddRoleStore<ApplicationRoleStore>()
        .AddUserStore<ApplicationUserStore>()
        .AddUserManager<ApplicationUserManager>()
        .AddRoleManager<ApplicationRoleManager>()
        .AddSignInManager<ApplicationSignInManager>()
        .AddDefaultTokenProviders();

    ...
    ...
    ...

    serviceCollection.AddSingleton(serviceProvider =>
    {
        //using (var currentContext = serviceProvider.CreateScope().ServiceProvider.GetRequiredService<MyIdentityDatabaseContext>())
        {
            return new IdentityOptions
            {
                Password = new PasswordOptions
                {
                    RequiredLength = 125
                }
            };
        }
    });
}

Example

public class TestController : BaseController<TestController>
{
    private readonly IOptions<IdentityOptions> _myOptions;

    public TestController(IOptions<IdentityOptions> myOptions)
    {
        _myOptions = myOptions;
    }

    [HttpGet]
    [Route("TestConfigureOptions")]
    public IActionResult TestConfigureOptions()
    {
        // 1 - Before assigning 124, the value it has is 6. WHY?

        _myOptions.Password.RequiredLength = 124;

        // 2 - After assigning the 124 and trying to create a user with an incorrect password length, I am informed that the minimum is 124, that this is correct.

        return Ok();
    }

}

Upvotes: 1

Views: 1397

Answers (1)

Nkosi
Nkosi

Reputation: 246998

Because those are two separate registrations.

AddIdentity would have added IdentityOptions via options using services.Configure<IdentityOptions>(...)

Which would allow IOptions<IdentityOptions> to be injected as expected.

The second registration

serviceCollection.AddSingleton(serviceProvider => { 

        return new IdentityOptions {
            Password = new PasswordOptions {
                RequiredLength = 125
            }
        };

});

has nothing to do with options.

If you would like to change the defaults then update the configuration.

serviceCollection.Configure<IdentityOptions>(options => {
    options.Password.RequiredLength = 125;
});

There is also an overload for when calling AddIdentity to do it in one go

serviceCollection.AddIdentity<ApplicationUser, ApplicationRole>(options => {
    options.Password.RequiredLength = 125;
})

Upvotes: 3

Related Questions