You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 8 Blazor中IOptions模式配置注入实现是否符合最佳实践?

关于Blazor中配置映射实现的最佳实践咨询

我正在学习.NET Core(Blazor),了解到有多种方式让组件获取appsettings.json中的配置。我倾向于通过类映射配置根节点的方式,因此尝试实现IOptions模式。当前使用Visual Studio 17.10.4、ASP.NET Core 8及对应SDK,代码可正常运行,但想咨询此实现方式是否恰当,是否需要调整及原因。

我的代码

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; } = [];
    }
}

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 Razor
builder.Services.AddRadzenComponents();                     

// Add my Event Console
builder.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();

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 ]
        }
      }
    }
  }
}

最佳实践分析与调整建议

1. 当前实现的合理性

你的代码是可行且合理的:

  • 由于明确配置在运行时不会修改,将AppOptions注册为单例(Singleton)是合适的,避免重复解析配置,提升性能。
  • 配置类的层级结构与appsettings.json中的AppSettings节点完全对应,组织清晰,便于维护和理解。

2. 符合官方最佳实践的优化方向

虽然当前实现可用,但更推荐使用ASP.NET Core官方的IOptions<T>模式,原因如下:

  • 规范性与生态一致性:IOptions<T>是官方推荐的配置注入方式,团队协作时更容易统一认知,与框架其他组件的使用方式保持一致。
  • 扩展性更强:后续如果需要支持配置热重载(即使现在不需要,预留扩展空间),可以无缝切换到IOptionsSnapshot<T>或IOptionsMonitor<T>,而无需修改依赖注入的消费端代码。
  • 支持配置验证:结合Microsoft.Extensions.Options.DataAnnotations包,可轻松给配置类添加数据验证规则(比如限制PageSize的取值范围),确保配置的合法性。

修改方式:
在Program.cs中将原注册代码替换为:

builder.Services.Configure<AppOptions>(builder.Configuration.GetSection("AppSettings"));

在组件或服务中通过注入IOptions<AppOptions>来获取配置:

private readonly AppOptions _appOptions;

public YourComponent(IOptions<AppOptions> appOptions)
{
    _appOptions = appOptions.Value;
}

3. 配置类的精简优化

  • 移除无用引用:AppOptions.cs中的using Microsoft.CodeAnalysis.CSharp.Syntax;没有实际作用,建议删除,减少代码冗余。
  • 调整可空类型:PageSizeOptions已经初始化了空列表,无需声明为List<int>?,改为List<int>即可,避免后续使用时的空值检查。
  • 可选:添加[Options]特性(需安装Microsoft.Extensions.Options.DataAnnotations包),为后续配置验证做准备:
using Microsoft.Extensions.Options;

namespace Licensing.Shared
{
    [Options]
    public class AppOptions
    {
        public Components Components { get; set; } = new Components();
    }

    // 其他类保持不变...
}

内容的提问来源于stack exchange,提问作者user7990543

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:49:59