Skip to content

Instantly share code, notes, and snippets.

@tonysneed
Created January 2, 2022 20:31
Show Gist options
  • Save tonysneed/53c2be11732ef78587c612880c777d99 to your computer and use it in GitHub Desktop.
Save tonysneed/53c2be11732ef78587c612880c777d99 to your computer and use it in GitHub Desktop.
Generic AddConfigSettings Extension method

Demo: Add App Settings To Dependency Injection

Demo to add app settings to dependency injection in a console app.

Problem

It is difficult to add app settings to dependency injection in a .NET console app.

Solution

Create a generic AddAppSettings extension method that can be called in ConfigureServices to bind a section in appsettings.json to IConfiguration using a strongly typed class.

  1. Add an appsettings.json file to a console app.
    • Set build action to Content, Copy to Output if newer.
{
  "MyAppSettings": {
    "StringSetting": "Hello App Settings",
    "IntSetting": 42,
    "BoolSetting": true
  }
}
  1. Create a class with a name that matches the settings section.
public class MyAppSettings
{
    public string StringSetting { get; set; }
    public int IntSetting { get; set; }
    public bool BoolSetting { get; set; }
}
  1. Add a ServiceCollectionExtensions class with a generic AddAppSettings extension method.
public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddAppSettings<TSettings>(this IServiceCollection services, IConfiguration config)
        where TSettings : class
    {
        services.Configure<TSettings>(
            config.GetSection(typeof(TSettings).Name));
        services.AddTransient(sp =>
            sp.GetRequiredService<IOptions<TSettings>>().Value);
        return services;
    }
}
  1. In Program.cs call Host.CreateDefaultBuilder, followed by .ConfigureServices in which you call services.AddAppSettings, passing IConfiguration.
var host = Host
    .CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        var config = services.BuildServiceProvider()
            .GetRequiredService<IConfiguration>();
        services.AddAppSettings<MyAppSettings>(config);
    })
    .Build();
  1. Call host.Services.GetRequiredService to get the settings and use them.
var settings = host.Services.GetRequiredService<MyAppSettings>();

Console.WriteLine("\nMy App Settings:");
Console.WriteLine($"String Setting: {settings.StringSetting}");
Console.WriteLine($"Int Setting: {settings.IntSetting}");
Console.WriteLine($"Bool Setting: {settings.BoolSetting}");
{
"MyAppSettings": {
"StringSetting": "Hello App Settings",
"IntSetting": 42,
"BoolSetting": true
}
}
public class MyAppSettings
{
public string StringSetting { get; set; }
public int IntSetting { get; set; }
public bool BoolSetting { get; set; }
}
// See https://aka.ms/new-console-template for more information
using Demo.AddAppSettingsToDepInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
Console.WriteLine("Add App Settings to Dependency Injection Demo");
var host = Host
.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
var config = services.BuildServiceProvider()
.GetRequiredService<IConfiguration>();
services.AddAppSettings<MyAppSettings>(config);
})
.Build();
var settings = host.Services.GetRequiredService<MyAppSettings>();
Console.WriteLine("\nMy App Settings:");
Console.WriteLine($"String Setting: {settings.StringSetting}");
Console.WriteLine($"Int Setting: {settings.IntSetting}");
Console.WriteLine($"Bool Setting: {settings.BoolSetting}");
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddAppSettings<TSettings>(this IServiceCollection services, IConfiguration config)
where TSettings : class
{
services.Configure<TSettings>(
config.GetSection(typeof(TSettings).Name));
services.AddTransient(sp =>
sp.GetRequiredService<IOptions<TSettings>>().Value);
return services;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment