Skip to content

Latest commit

 

History

History
80 lines (47 loc) · 5.09 KB

custom-configuration-provider.md

File metadata and controls

80 lines (47 loc) · 5.09 KB
title description author ms.author ms.date ms.topic
Implement a custom configuration provider
Learn how to implement a custom configuration provider in .NET apps. Explore a database configuration provider that uses Entity Framework Core.
IEvangelist
dapine
02/20/2024
how-to

Implement a custom configuration provider in .NET

There are many configuration providers available for common configuration sources such as JSON, XML, and INI files. You may need to implement a custom configuration provider when one of the available providers doesn't suit your application needs. In this article, you'll learn how to implement a custom configuration provider that relies on a database as its configuration source.

Custom configuration provider

The sample app demonstrates how to create a basic configuration provider that reads configuration key-value pairs from a database using Entity Framework (EF) Core.

The provider has the following characteristics:

  • The EF in-memory database is used for demonstration purposes.
    • To use a database that requires a connection string, get a connection string from an interim configuration.
  • The provider reads a database table into configuration at startup. The provider doesn't query the database on a per-key basis.
  • Reload-on-change isn't implemented, so updating the database after the app has started will not affect the app's configuration.

Define a Settings record type entity for storing configuration values in the database. For example, you could add a Settings.cs file in your Models folder:

:::code language="csharp" source="snippets/configuration/custom-provider/Models/Settings.cs":::

For information on record types, see Record types in C#.

Add an EntityConfigurationContext to store and access the configured values.

Providers/EntityConfigurationContext.cs:

:::code language="csharp" source="snippets/configuration/custom-provider/Providers/EntityConfigurationContext.cs":::

By overriding xref:Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder) you can use the appropriate database connection. For example, if a connection string was provided you could connect to SQL Server, otherwise you could rely on an in-memory database.

Create a class that implements xref:Microsoft.Extensions.Configuration.IConfigurationSource.

Providers/EntityConfigurationSource.cs:

:::code language="csharp" source="snippets/configuration/custom-provider/Providers/EntityConfigurationSource.cs":::

Create the custom configuration provider by inheriting from xref:Microsoft.Extensions.Configuration.ConfigurationProvider. The configuration provider initializes the database when it's empty. Since configuration keys are case-insensitive, the dictionary used to initialize the database is created with the case-insensitive comparer (StringComparer.OrdinalIgnoreCase).

Providers/EntityConfigurationProvider.cs:

:::code language="csharp" source="snippets/configuration/custom-provider/Providers/EntityConfigurationProvider.cs":::

An AddEntityConfiguration extension method permits adding the configuration source to the underlying ConfigurationManager instance.

Extensions/ConfigurationManagerExtensions.cs:

:::code language="csharp" source="snippets/configuration/custom-provider/Extensions/ConfigurationManagerExtensions.cs":::

Since the xref:Microsoft.Extensions.Configuration.ConfigurationManager is both an implementation of xref:Microsoft.Extensions.Configuration.IConfigurationBuilder and xref:Microsoft.Extensions.Configuration.IConfigurationRoot, the extension method can access the connection strings configuration and add the EntityConfigurationSource.

The following code shows how to use the custom EntityConfigurationProvider in Program.cs:

:::code language="csharp" source="snippets/configuration/custom-provider/Program.cs" highlight="9":::

Consume provider

To consume the custom configuration provider, you can use the options pattern. With the sample app in place, define an options object to represent the widget settings.

:::code language="csharp" source="snippets/configuration/custom-provider/WidgetOptions.cs":::

A call to xref:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure%2A registers a configuration instance, which TOptions binds against.

:::code language="csharp" source="snippets/configuration/custom-provider/Program.cs" highlight="14,16-19":::

The preceding code configures the WidgetOptions object from the "WidgetOptions" section of the configuration. This enables the options pattern, exposing a dependency injection-ready IOptions<WidgetOptions> representation of the EF settings. The options are ultimately provided from the custom configuration provider.

See also