I am learning .NET Core (Blazor) and read many tutorials and guides. There appear to be many ways to cook the egg trying to get appsettings.json available to my components. I like the idea of mapping a class over the structure of appsettings at a root element, and so I am coding (or trying to) an IOptions pattern.Is this the appropriate way - does it need tweaking and if so why?
I'm using Visual Studio 17.10.4, ASP.NET Core 8 and SDK.
Here is my Options class AppOptions.cs
using Microsoft.CodeAnalysis.CSharp.Syntax;namespace Licensing.Shared{ public class AppOptions { public Components Components { get; set; } = new Components(); } public class Components { public Pages Pages { get; set; } = new Pages(); } public class Pages { public Table Table { get; set; } = new Table(); } public class Table { public int PageSize { get; set; } = default; public List<int>? PageSizeOptions { get; set; } = []; }}and here Program.cs
using Licensing.Components;using Radzen;using Microsoft.EntityFrameworkCore;using Microsoft.Extensions.DependencyInjection;using Licensing.Data;using Licensing.Components.Utils;using Licensing.Shared;var builder = WebApplication.CreateBuilder(args);builder.Services.AddDbContextFactory<LicensingContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("LicensingContext") ?? throw new InvalidOperationException("Connection string 'LicensingContext' not found.")));//builder.Services.AddQuickGridEntityFrameworkAdapter();builder.Services.AddDatabaseDeveloperPageExceptionFilter();// Add services to the container.builder.Services.AddRazorComponents() .AddInteractiveServerComponents();// Add Razorbuilder.Services.AddRadzenComponents(); // Add my Event Consolebuilder.Services.AddScoped<EventConsole>();// --------THIS--------// This is a singleton (static) service where the scope exists across the app (all settings will not change in appsettings.json at run-time).builder.Services.AddSingleton<AppOptions>(builder.Configuration.GetSection("AppSettings").Get<AppOptions>());var app = builder.Build();// Configure the HTTP request pipeline.if (!app.Environment.IsDevelopment()){ app.UseExceptionHandler("/Error", createScopeForErrors: true); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); app.UseMigrationsEndPoint();}app.UseHttpsRedirection();app.UseStaticFiles();app.UseAntiforgery();app.MapRazorComponents<App>() .AddInteractiveServerRenderMode();app.Run();`and appsettings.json
{"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning" } },"AllowedHosts": "*","ConnectionStrings": {"LicensingContext": "Server=(localdb)\\mssqllocaldb;Database=LicensingContext-5acfd89b-2b0c-4df3-a82f-719fdcde315b;Trusted_Connection=True;MultipleActiveResultSets=true" },"AppSettings": {"Components": {"Pages": {"Table": {"PageSize": 6,"PageSizeOptions": [ 4, 6, 10, 30 ] } } } }}I have tried as documented in this post - I'm not seeking to correct code, but rather querying my implementation and best-practice. Everything appears to "work" with no issues.