Chris Chris - 2 months ago 20
ASP.NET (C#) Question

Using IConfigureOptions to configure an injected dependency

I have created an ASP.NET Core 1.0.1 WebApi project and am trying to initialize an injected dependency with some custom options before using it in my controllers. After searching online I found a few articles (here, here and here explaining how to use IConfigureServices to do just this. Seems pretty simple! Unfortunately, I can't get it to work and I can't figure out why, I'm sure it must be a simple oversight..

I have created a simple project, and added the following classes to illustrate the most basic scenario:

public class Tester
{
public void Initialize(TestOptions options)
{
//do something with options.
}
}

public class TestConfigurator : IConfigureOptions<TestOptions>
{
private Tester _tester;

public TestConfigurator(Tester tester)
{
_tester = tester;
}

public void Configure(TestOptions options)
{
_tester.Initialize(options);
}
}

public class TestOptions
{
}


The 'Tester' class gets injected into the constructor of a Controller class:

[Route("api/[controller]")]
public class ValuesController : Controller
{
public ValuesController(Tester tester)
{
//do something with tester..
}
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}


Finally, I have added the following configuration in ConfigureServices of the Startup class:

public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddOptions();
services.AddMvc();
services.AddSingleton<Tester, Tester>();
services.AddSingleton<IConfigureOptions<TestOptions>, TestConfigurator>();
}


When I run the project and call the 'api/values' call, the Tester class is created and injected into the ValuesController, but the TestConfigurator class never gets constructed and so the class never gets Initialized with the options class. What am I missing?

Answer

Ok, now I got it, I feel silly for all the edits.

you are using IOptions wrong, and it got me all confused.

implementing a custom IConfigurationOptions<> gives you the abilty to either configure your options from database, or to just use a different class (instead of a lambda)

what you are trying to do, is instantiate a Tester class based on those options, this is fine - but it's not the IConfigureOptions<> job.

in order to initialize your Tester class based on the TestOptions you should create a constructor on the Tester class that receives it like this

public class Tester
{
    public Tester(IOptions<TestOptions> options)
    {
        //do something with options.
    }
}

and what you are trying to do will work.

Comments