Application configuration
.NET .NET Core Best Practices C# Dependency Injection Patterns Visual Studio

Using the IOptions Pattern in a .Net Core Application

Hi and welcome back to my blogs on development!

Today I will go over how you can use the IOptions pattern to inject application settings within your .NET Core applications using dependency injection into .NET Core 3.1.

The file used to store configuration settings for our .NET Core web application is the appsettings.json file. A sample format of this file is shown as follows:

{
  "ConnectionStrings": {
    "AppDbContext": "[some connection string]"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AppSettings": {
    "AppName": "BookLoan",
    "AppVersion": "1.0.0",
    "AlertEmail": operator@bookloan.com,
    "UrlCatalogAPI": "http://localhost/BookLoan.Catalog.API/",
    "UrlLoanAPI": "http://localhost/BookLoan.Loan.API/"
  }
}

To obtain a connection string, we can use the following command:

string dbConnStr = Configuration.GetConnectionString("AppDbContext")

where Configuration is injected through a constructor, e.g. from Startup():

public IConfiguration Configuration { get; }

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

This is quite straightforward, and similar to traditional .NET 4.x Framework applications.

How about the key / value pairs in the AppSettings section?

The following will also work:

string sAppName = Configuration.GetValue<string>("AppSettings:AppName");
string sAppVersion = Configuration.GetValue<string>("AppSettings:AppVersion");

If we had numerous settings key / values to retrieve into our service classes, the above would be quite cumbersome and repeat itself. The solution to this is to use the IOptions pattern from .NET Core framework 2.2/3.1.  The IOptions pattern allows us to make configuration access strongly types by mapping application settings into a concrete application type model instance that is accessible through the use of dependency injection anywhere within our application classes.

These are the steps to take to use IOptions:

Step 1

Create a class to containing your application settings:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace BookLoan.Services
{
    public class AppConfiguration
    {
        public AppConfiguration() { } 
        public string AppName { get; set; } 
        public string AppVersion { get; set; } 
        public string UrlCatalogAPI { get; set; }
        public string UrlLoanAPI { get; set; }
    }
}
Step 2

In your ConfigureServices() method within startup.cs add the following two lines:

public void ConfigureServices(IServiceCollection services)
{
    …            
    services.Configure<AppConfiguration>(
        Configuration.GetSection("AppSettings"));
		…
}

We include the following namespace at the top of the source.

Microsoft.Extensions.Configuration

By including the options pattern into your services container, allows your application to map the equivalent settings from appSettings.json into your application configuration model.

Step 3

Inject IOptions into a custom service class. Reference the configuration data within your service class and obtain settings properties:

using Microsoft.Extensions.Options;
…

public class BookService: IBookService
{
    …
    private readonly IOptions<AppConfiguration> _appConfiguration;

    public BookService(..., IOptions<AppConfiguration> appConfiguration, …)
    {
        ...
        _appConfiguration = appConfiguration;
    }
    …
Step 4

Obtain the application configuration value from the options manager:

public async Task<List<BookViewModel>> GetBooks()
{
    ...

    HttpResponseMessage response = null;
    var delayedRetry = _apiServiceRetryWithDelay;

    await delayedRetry.RunAsync(async () =>
    {
        response = await _apiServiceHelper.GetAPI(
            _appConfiguration.Value.UrlCatalogAPI + "api/Book/List",
            null,
            bearerToken
        );
    });
    ...

Use of the IOptions pattern gives you a cleaner way to inject application configuration settings into your application classes and handles the lifetime of the application configuration data for you.

In addition, it makes the configuration access strongly typed.

That’s all for today’s post.

I hope you found this post useful and informative.

Social media & sharing icons powered by UltimatelySocial