# dotnet core console application IOptions<T> configuration

So, I’m losing faith in my google skills, there didn’t seem to be a one stop shop that I could find to give information on setting up a .net core console application with a IServiceProvider and utilizing IOptions<T>… so that brings us here.

In the process of needing configuration for the first time in a console app — crazy I know. The project is currently using AutoFac as its IOC container — though having to look into .netcore’s built in IOC container, I may want to switch to it!

The basis of wanting to utilize configuration for the app for the first time is utilizing differing endpoints for external resources, depending on the environment. These configuration values would be loaded at the applications entry point (or thereabouts) and would need to be accessed deep within the internals of the app, very likely not even within the same project.

How can I do this without having to set some static member somewhere in which everything has access? That led me to find IOptions<T> (Doc) — T being a configuration class. IOptions<T> allows for the injection of configuration values into a class, this is exactly what’s needed, and avoids the thing I was worried about having to either pass a configuration collection all over the call stack, or using a static member somewhere in the app.

The first thing we need to do in the console app, is to create a configuration file.

appsettings.json :

and load it in the entry point of our console app

Program.cs :

Ok! File loaded, it currently does nothing! Next, we’ll want to load an environment specific json file, but in order to do that, we’ll need a concept of an environment. Seems like the environment is often controlled via an “environment variable” (no relation?). There are various ways to set environment variables, depending on OS. Some of those methods include:

I’m going to set a new environment variable for a seemingly standard ASPNETCORE_ENVIRONMENT to “local”. Another sample environment we’ll use is “test”.

Now we can go about creating a few new configuration files for the other environments.

appsettings.local.json :

appsettings.test.json

Now we have a “base” configuration appsettings.json, and environment specific configurations appsettings.local.json and appsettings.test.json. This coupled with our new environment variable should allow us to start working with some configuration in a meaningful way (pretty soon).

For now, let’s take a look at what loading the different environment configuration files looks like. From our original example of Program.cs

In this above, you can see we’re loading into env the value stored in the environment variable ASPNETCORE_ENVIRONMENT, when/if this variable isn’t available we (currently) throw an exception. We then print the environment variable value we loaded, and finally load the appropriate appsettings.{env}.json. You can see the loaded environment changes depending on the value of the environment variable ASPNETCORE_ENVIRONMENT.

Now that we’re successfully loading configuration files based on an environment variable, let’s get into some IOptions.

First thing we’ll need is a configuration class, we’ll do something nice and simple like environment specific configuration for a API endpoint:

ApiConfig.cs

In the above we just have a class defined, and we would create json to represent those classes in each of our environment configuration files.

appsettings.local.json

appsettings.test.json

We now have enough “stuff” in place that we can load something into an IOptions<T> — our ApiConfig, or IOptions<ApiConfig>.

We’ll make another change to our Program ctor:

A few new things above:

• serviceCollection — where we register our services
• ServiceProvider — where we “get” our registered services.

We can now “resolve” our registered components as per the normal dotnetcore resolver, and our new IOptions<T> can be used like so:

SomeClass.cs

The environment configuration loaded will determine which “instance” of ApiConfig we inject into SomeClass.

One last hiccup on my end, is I’m actually using AutoFac, and not the .net core IOC container . Due to this all my resolutions are occurring through AutoFac, while my IOptions<T> are being registered through .net core’s IOC container.

This is another pretty simple change (though it at least took me a while to figure it out). I ended up throwing together a new helper method that takes in my IServiceProvider, as well as my ContainerBuilder (from AutoFac registration). The helper method looks like:

and can be called directly from our normal composition root/entry point that puts together the AutoFac container.