How to configure dependencies in startup using the options pattern?

Viewed 281

In ASP.NET Core ConfigureServices Startup method you can do things such as

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true))
        };
    });

I want to do something like this on startup to configure my own dependency.

services.AddTest(options =>
    new TestOptions
    {
        TestNumber = 8
    });

This is my extension method that chains onto IServiceCollection...

public static IServiceCollection AddTest(this IServiceCollection services, Action<TestOptions> options)
{
    services.AddScoped<ITest, Test>();

    if (options != null)
    {
        services.Configure(options);
    }

    return services;
}

and my TestOptions is just a simple model...

public class TestOptions
{
    public int? TestNumber { get; set; }
}

Then, finally I pass those options through to the constructor of the class I want to use them...

public Test (IConfiguration configuration, IOptions<TestOptions> options)
{
    LocalTestNumber = options.Value.TestNumber;
}

However, when I hit the breakpoint on LocalTestNumber = options.Value.TestNumber the TestNumber is null and I'm not sure why, anyone have any insight on this?

I followed this tutorial to do this... https://codeburst.io/options-pattern-in-net-core-a50285aeb18d

1 Answers

The problem is in this part of the code you've shown:

services.AddTest(options =>
    new TestOptions
    {
        TestNumber = 8
    });

Instead of creating and returning a new instance of TestOptions, which gets discarded, configure the options argument that gets passed in. Here's the fixed version:

services.AddTest(options => options.TestNumber = 8);
Related