RSCG – NotNotAppSettings

RSCG – NotNotAppSettings
 
 

name NotNotAppSettings
nuget https://www.nuget.org/packages/NotNot.AppSettings/
link https://github.com/jasonswearingen/NotNot.AppSettings/
author jasonswearingen

Application Settings to strongly typed classes. Generate also from AppSettings development

 

This is how you can use NotNotAppSettings .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <InvariantGlobalization>true</InvariantGlobalization>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.1" />
    <PackageReference Include="NotNot.AppSettings" Version="1.0.0" OutputItemType="Analyzer" ReferenceOutputAssembly="true" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
  </ItemGroup>

  <ItemGroup>
    <AdditionalFiles Update="appsettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </AdditionalFiles>
  </ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddSingleton<TestAppSettings.AppSettingsGen.IAppSettingsBinder, TestAppSettings.AppSettingsGen.AppSettingsBinder>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

var summaries = new[]
{
    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

var appSettings = app.Services.GetRequiredService<TestAppSettings.AppSettingsGen.IAppSettingsBinder>().AppSettings;
Console.WriteLine(appSettings.AppName);

app.MapGet("/weatherforecast", () =>
{
    var forecast = Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi();

app.Run();

internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}


 

The code that is generated is


/** 
 * This file is generated by the NotNot.AppSettings nuget package.
 * Do not edit this file directly, instead edit the appsettings.json files and rebuild the project.
**/
using System;
using System.Runtime.CompilerServices;
namespace TestAppSettings.AppSettingsGen;

[CompilerGenerated]
public partial class AppSettings {
   public TestAppSettings.AppSettingsGen._AppSettings.Logging? Logging{get; set;}
   public string? AllowedHosts{get; set;}
   public string? AppName{get; set;}

}


/** 
 * This file is generated by the NotNot.AppSettings nuget package.
 * Do not edit this file directly, instead edit the appsettings.json files and rebuild the project.
**/
using System;
using System.Runtime.CompilerServices;
namespace TestAppSettings.AppSettingsGen._AppSettings;

[CompilerGenerated]
public partial class Logging {
   public TestAppSettings.AppSettingsGen._AppSettings._Logging.LogLevel? LogLevel{get; set;}

}


/** 
 * This file is generated by the NotNot.AppSettings nuget package.
 * Do not edit this file directly, instead edit the appsettings.json files and rebuild the project.
**/
using System;
using System.Runtime.CompilerServices;
namespace TestAppSettings.AppSettingsGen._AppSettings._Logging;

[CompilerGenerated]
public partial class LogLevel {
   public string? Default{get; set;}
   public string? Microsoft_AspNetCore{get; set;}

}


/** 
 * This file is generated by the NotNot.AppSettings nuget package.
 * Do not edit this file directly, instead edit the appsettings.json files and rebuild the project.
**/

using Microsoft.Extensions.Configuration;
namespace TestAppSettings.AppSettingsGen;


/// <summary>
/// Strongly typed AppSettings.json, recreated every build. 
/// <para>You can use this directly, extend it (it's a partial class), 
/// or get a populated instance of it via the <see cref="AppSettingsBinder"/> DI service</para>
/// </summary>
public partial class AppSettings
{
}

/// <summary>
/// a DI service that contains a strongly-typed copy of your appsettings.json
/// <para><strong>DI Usage:</strong></para>
/// <para><c>builder.Services.AddSingleton&lt;IAppSettingsBinder, AppSettingsBinder&gt;();</c></para>
/// <para><c>var app = builder.Build();</c></para>
///  <para><c>var appSettings = app.Services.GetRequiredService&lt;IAppSettingsBinder&gt;().AppSettings;</c></para>
/// <para><strong>Non-DI Usage:</strong></para>
/// <para><c>var appSettings = AppSettingsBinder.LoadDirect();</c></para>
/// </summary>
public partial class AppSettingsBinder : IAppSettingsBinder
{
   public AppSettings AppSettings { get; protected set; }

   public AppSettingsBinder(IConfiguration _config)
   {
      AppSettings = new AppSettings();

      //automatically reads and binds to config file
      _config.Bind(AppSettings);
   }

   /// <summary>
   /// Manually construct an AppSettings from your appsettings.json files.
   /// <para>NOTE: This method is provided for non-DI users.  If you use DI, don't use this method.  Instead just register this class as a service.</para>
   /// </summary>
   /// <param name="appSettingsLocation">folder where to search for appsettings.json.  defaults to current app folder.</param>
   /// <param name="appSettingsFileNames">lets you override the files to load up.  defaults to 'appsettings.json' and 'appsettings.{DOTNET_ENVIRONMENT}.json'</param>
   /// <param name="throwIfFilesMissing">default is to silently ignore if any of the .json files are missing.</param>
   /// <returns>your strongly typed appsettings with values from your .json loaded in</returns>
   public static AppSettings LoadDirect(string? appSettingsLocation = null,IEnumerable<string>? appSettingsFileNames=null,bool throwIfFilesMissing=false )
   {      
      //pick what .json files to load
      if (appSettingsFileNames is null)
      {
         //figure out what env
         var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
         env ??= Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");
         env ??= Environment.GetEnvironmentVariable("ENVIRONMENT");
         //env ??= "Development"; //default to "Development
         if (env is null)
         {
            appSettingsFileNames = new[] { "appsettings.json" };
         }
         else
         {
            appSettingsFileNames = new[] { "appsettings.json", $"appsettings.{env}.json" };
         }
      }

      //build a config from the specified files
      var builder = new ConfigurationBuilder();
      if (appSettingsLocation != null)
      {
         builder.SetBasePath(appSettingsLocation);
      }
      var optional = !throwIfFilesMissing;
      foreach (var fileName in appSettingsFileNames)
      {         
         builder.AddJsonFile(fileName, optional: optional, reloadOnChange: false); // Add appsettings.json
      }
      IConfigurationRoot configuration = builder.Build();

      //now finally get the appsettings we care about
      var binder = new AppSettingsBinder(configuration);
      return binder.AppSettings;
   }
}

/// <summary>
/// a DI service that contains a strongly-typed copy of your appsettings.json
/// <para><strong>DI Usage:</strong></para>
/// <para><c>builder.Services.AddSingleton&lt;IAppSettingsBinder, AppSettingsBinder&gt;();</c></para>
/// <para><c>var app = builder.Build();</c></para>
///  <para><c>var appSettings = app.Services.GetRequiredService&lt;IAppSettingsBinder&gt;().AppSettings;</c></para>
/// <para><strong>Non-DI Usage:</strong></para>
/// <para><c>var appSettings = AppSettingsBinder.LoadDirect();</c></para>
/// </summary>
public interface IAppSettingsBinder
{
   public AppSettings AppSettings { get; }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/NotNotAppSettings