MoneyTree.Web 1.0.4

MoneyTree.Web Web 集成

📋 概述

MoneyTree.Web 是框架的 Web 集成模块,统一所有模块的 Web 入口,提供静态启动方法(MoneyTreeHost)、全局异常处理、请求日志、ApiResult 自动包装、CurrentUser 自动填充、SSE 支持等中间件和过滤器,并以 NLog 作为默认日志组件。

属性 说明
NuGet 包 MoneyTree.Web
外部依赖 MoneyTree.CoreASP.NET CoreNLog.Web.AspNetCore
定位 统一 Web 入口与中间件集成

🏗️ 项目文件结构

MoneyTree.Web/
├── MoneyTree.Web.csproj
├── GlobalUsings.cs
├── Host/
│   └── MoneyTreeHost.cs                 # 静态启动入口
├── Middlewares/
│   ├── GlobalExceptionMiddleware.cs     # 全局异常处理
│   ├── HmacAuthMiddleware.cs            # HMAC 认证中间件
│   └── RequestLoggingMiddleware.cs      # 请求日志记录
├── Extensions/
│   ├── ClaimsPrincipalExtensions.cs     # ClaimsPrincipal 扩展
│   ├── HmacHttpClientExtensions.cs      # HMAC HttpClient 扩展
│   ├── SseExtensions.cs                 # SSE 流式响应扩展
│   └── WebDefaultsExtensions.cs         # 默认 Web 配置扩展
├── Filters/
│   └── ApiResultFilter.cs               # ApiResult 自动包装过滤器
├── HttpHandlers/
│   └── HmacAuthHandler.cs               # HMAC 签名请求处理器
├── Options/
│   └── HmacAuthOptions.cs               # HMAC 认证配置选项
└── ProblemDetails/
    └── ProblemDetailsFactory.cs         # 标准 Problem Details 工厂

🎯 核心能力

能力 实现 说明
NLog 默认日志 预置 NLog 配置 自动集成,输出到控制台和文件
全局异常处理 GlobalExceptionMiddleware 自动转换为 ApiResult 格式
请求日志 RequestLoggingMiddleware 自动记录请求耗时、状态码
ApiResult 自动包装 ApiResultFilter 响应自动包装为 ApiResult 格式
CurrentUser 填充 ClaimsPrincipalExtensions 通过 ClaimsPrincipal 扩展方法获取当前用户
SSE 支持 SseExtensions IAsyncEnumerable 转 text/event-stream
SignalR 兼容 原生兼容 中间件管道与 SignalR 原生兼容
健康检查 内置端点 /health/ready/live 端点
一键启用 AddMoneyTreeDefaults() / UseMoneyTreeDefaults() 快速集成所有中间件

🚀 静态 Program 入口

MoneyTreeHost 提供多种启动方式,从最简单的一行代码到复杂的自定义配置。

方式一:最简启动(无参数)

// Program.cs — 一行启动
MoneyTreeHost.Run();

自动读取 appsettings.json,使用默认配置。

方式二:带数据库配置

MoneyTreeHost.Run(db =>
{
    db.UsePostgreSql("Host=localhost;Database=mydb");
});

方式三:带完整配置委托

MoneyTreeHost.Run(app =>
{
    app.UsePostgreSql("Host=localhost;Database=mydb");
    app.UseRedis("localhost:6379");
    app.UseMultiTenancy(m => m.UseHeader("X-Tenant-Id"));
    app.UseTelemetry(t => t.UseOpenTelemetryCollector());
    app.UseResilience(r => r.Defaults.SetRetry(3));
    app.UseApiVersioning(v => v.UseUrlPath());
    app.UseCors("http://localhost:3000");
});

方式四:自定义配置类(推荐生产环境)

public class AppConfig : IMoneyTreeAppConfig
{
    public void ConfigureDatabase(DatabaseOptions db)
    {
        db.UsePostgreSql("Host=localhost;Database=mydb");
    }

    public void ConfigureMultiTenancy(MultiTenancyOptions mt)
    {
        mt.UseHeader("X-Tenant-Id");
    }

    public void ConfigureCaching(CachingOptions cache)
    {
        cache.UseRedis("localhost:6379");
    }

    public void ConfigureTelemetry(TelemetryOptions telemetry)
    {
        telemetry.UseOpenTelemetryCollector();
    }

    public void ConfigureResilience(ResilienceOptions resilience)
    {
        resilience.Defaults.SetRetry(3);
    }
}

// Program.cs — 一行启动
MoneyTreeHost.Run<AppConfig>();

方式五:带参数解析

// 自动解析命令行参数或环境变量
MoneyTreeHost.Run(args, app =>
{
    var connectionString = app.Configuration.GetConnectionString("Default");
    app.UsePostgreSql(connectionString!);
    app.UseRedis(app.Configuration["Redis:ConnectionString"]!);
});

📋 IMoneyTreeAppConfig 接口

方法 说明
ConfigureDatabase(DatabaseOptions db) 数据库配置,可选实现
ConfigureMultiTenancy(MultiTenancyOptions mt) 多租户配置,可选实现
ConfigureCaching(CachingOptions cache) 缓存配置,可选实现
ConfigureTelemetry(TelemetryOptions telemetry) 遥测配置,可选实现
ConfigureResilience(ResilienceOptions resilience) 弹性配置,可选实现
ConfigureApiVersioning(ApiVersioningOptions versioning) API 版本配置,可选实现
ConfigureCors(CorsOptions cors) 跨域配置,可选实现
ConfigureServices(IServiceCollection services) 自定义服务注册
ConfigureMiddleware(IApplicationBuilder app) 自定义中间件

业务系统只需实现关心的配置方法,其余使用框架默认值。


📖 使用示例

配置服务和中间件

// Program.cs
MoneyTreeHost.Run(args,
    configureBuilder: builder =>
    {
        builder.Services.AddScoped<IMyService, MyService>();
    },
    configureApp: (builder, app) =>
    {
        app.UseMiddleware<MyMiddleware>();
    });

抛出业务异常

在服务中抛出的异常自动被 GlobalExceptionMiddleware 捕获并转换为 ApiResult 格式:

public class OrderService
{
    public async Task<Order> GetAsync(string id)
    {
        var order = await _db.Orders.FindAsync(id);
        return order ?? throw new NotFoundException("订单", id);
    }

    public async Task CancelAsync(string id)
    {
        var order = await _db.Orders.FindAsync(id);
        if (order.Status == OrderStatus.Shipped)
        {
            throw new DomainException("已发货的订单无法取消", 409, "ORDER_SHIPPED");
        }
    }
}

获取当前用户

在 Controller 或 Minimal API 中:

app.MapGet("/api/me", (ClaimsPrincipal user) =>
{
    var currentUser = user.ToCurrentUser();
    return Results.Ok(new { currentUser.Id, currentUser.UserName });
});

在服务中使用(通过 IHttpContextAccessor):

public class OrderService
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    private ICurrentUser CurrentUser =>
        _httpContextAccessor.HttpContext?.User.ToCurrentUser()
        ?? CurrentUser.Core.CurrentUser.Anonymous;
}

SSE 终结点

app.MapGet("/api/notifications", (HttpResponse response) =>
{
    var stream = GetNotificationStream();
    return stream.ToSseResult("notification");
});

📝 NLog 默认配置

框架预置 nlog.configAddMoneyTreeDefaults() 自动注册 NLog:

<nlog>
  <targets>
    <target name="console" xsi:type="Console" />
    <target name="file" xsi:type="File"
            fileName="logs/${shortdate}.log"
            layout="${longdate}|${level}|${logger}|${message}|${exception:format=tostring}" />
  </targets>
  <rules>
    <logger name="Microsoft.*" maxLevel="Warn" final="true" />
    <logger name="*" minLevel="Info" writeTo="console,file" />
  </rules>
</nlog>
NLog 集成特性 说明
自动配置 框架内置默认 nlog.config,开箱即用
结构化日志 自动注入 TraceId、TenantId、UserId
Telemetry 联动 日志与 OpenTelemetry Traces 自动关联

Hmac使用示例

方式一:直接指定密钥

// Program.cs builder.Services.AddHttpClient("PaymentService", client => { client.BaseAddress = new Uri("https://payment.example.com"); }) .AddHmacAuthHandler("order-service", "your-secret-key");

方式二:从配置中心读取密钥

// Program.cs builder.Services.AddHttpClient("NotificationService", client => { client.BaseAddress = new Uri("https://notification.example.com"); }) .AddHmacAuthHandler("order-service"); // 自动从 IConfiguration 读取密钥

方式三:在服务中使用

public class OrderService { private readonly IHttpClientFactory _httpClientFactory;

public OrderService(IHttpClientFactory httpClientFactory)
{
    _httpClientFactory = httpClientFactory;
}

public async Task CreatePaymentAsync(CreatePaymentRequest request)
{
    var client = _httpClientFactory.CreateClient("PaymentService");
    // 请求自动携带 HMAC 签名头,无需手动处理
    var response = await client.PostAsJsonAsync("/api/payment/create", request);
}

}

No packages depend on MoneyTree.Web.

Version Downloads Last updated
1.0.6 1 7/21/2026
1.0.4 1 7/12/2026