MIT License

技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

fullstackhero/dotnet-starter-kit 深度拆解:一个把“企业级脚手架”做成产品的 .NET 10 起点

项目背景与痛点

.NET 生态里从不缺脚手架,缺的是“开箱即可进生产”的那个。dotnet new webapi 给你一个空壳,ABP 给你一整套框架但也带来一整套约束,而大多数自研模板在半年后就会烂在某个架构师离职的 PR 里。

fullstackhero/dotnet-starter-kit 的定位很明确:它要消灭的是项目启动阶段最昂贵、最无趣、也最容易做错的那 200 小时——多租户隔离方案怎么选、模块之间怎么解耦、认证授权与权限点怎么落地、EF Core 的全局过滤器怎么配、缓存 key 怎么带租户前缀、后台任务怎么跑、Docker Compose 怎么编排、前端怎么接 CQRS 风格的接口。

这些问题的共同点是:它们不是业务问题,但做错了就变成长期的架构债。而这个仓库的价值就在于,它把这些问题的最佳实践固化成了可运行的代码,而不是一篇文档。

核心技术揭秘

它的架构骨架由三层组成:Building Blocks(可复用的基础设施)、Modules(业务模块)、Host(组装层)。这不是简单的分层,而是一次刻意的“物理隔离”:模块之间不允许直接引用对方的实现,只能依赖对方的 Contracts 项目。这条纪律靠项目引用的依赖关系强制约束,而不是靠 Code Review 的自觉。

数据流的核心枢纽是 MediatR。每个模块内部按 CQRS 划分为 Command / Query,请求进入后先过 FluentValidation 的行为管道,再进入 Handler,Handler 只依赖抽象仓储与领域事件总线。返回值统一走 Mapster 投影成 DTO,避免实体泄漏到 API 边界。

多租户是整套方案的技术重心。它建立在 Finbuckle.MultiTenant 之上:租户来源支持 Header、Claim、Host 多种策略,解析结果落到一个可注入的租户上下文里,并向下贯穿到 EF Core。关键点在于 全局查询过滤器 + 缓存键前缀 的双重隔离——数据库层面用 TenantId 拦住越权读,缓存层面用租户前缀避免脏读。对于需要独立库的大客户,它保留切换到独立数据库连接的扩展位,这是 SaaS 产品从中小客户走向企业客户时必须面对的分叉。

graph TD A[React 客户端<br/>Vite + TanStack Query] --> B[ASP.NET Core Host<br/>统一组装层] B --> C{"租户解析中间件"} C -->|"Header / Claim / Host"| D[注入租户上下文] C -->|"无法识别"| E[拒绝请求] D --> F[认证与授权<br/>权限点校验] F --> G[MediatR 请求管道] G --> H[FluentValidation 校验] H --> I[模块 Handler<br/>仅依赖 Contracts] I --> J[EF Core<br/>全局查询过滤器] J --> K[PostgreSQL 租户数据] I --> L[事件总线] L --> M[缓存失效] L --> N[Hangfire 后台任务]

另一个值得注意的设计是模块内的审计与事件。几乎每个实体操作都会产生审计记录和领域事件,事件再被分发到缓存失效、通知、Webhook 等订阅方。这种“写操作必须留下痕迹”的默认行为,在企业场景里通常意味着省掉一轮自研成本。

功能亮点与差异

与 ABP 相比,它的差异不在功能数量,而在约束的松紧度。ABP 是一套完整框架,你必须接受它的抽象;而这个 starter kit 更像一组“你已经想这么写,但还没写完”的代码——你可以拆掉任何一个模块,代价是可计算的。

真正拉开差距的几点:一是模块化落地到了项目引用级别,而非文件夹级别,这在 .NET 生态里并不常见;二是多租户不是可选插件而是内建主线,从数据库到缓存到日志全都带租户上下文;三是前后端一起交付,React 端用的是 TanStack Query + shadcn 这套当下主流组合,接口契约直接对齐后端 CQRS 结构,省掉了前后端定义接口的那轮扯皮。

应用场景与落地建议

它最适合的场景是:面向 B 端的多租户 SaaS 产品、需要快速验证的中台项目、以及团队已有 .NET 经验但缺少架构共识的情况。不适合的场景同样明确——单体小工具、极高性能要求的服务端、以及团队完全不想理解 CQRS 的项目。

生产落地有几个坑必须提前想清楚:

  • 跨租户操作:全局过滤器是双刃剑,后台任务、平台级管理员、数据迁移都必须显式绕过它,务必封装备受控的 IgnoreQueryFilters 入口,否则一次误用就是数据事故。
  • 独立库租户的迁移:共享库模式下 dotnet ef migrations 一次搞定,独立库模式下迁移编排会变成运维问题,建议一开始就把迁移做成自动化流水线。
  • 事件可靠性:进程内事件总线足够快,但不保证投递。涉及资金、库存、通知的场景,需要引入 Outbox 模式,不要假设事件一定送达。
  • 模块边界治理:Contracts 的膨胀是最常见的腐化路径。定期审查 Contracts,凡是实现细节混进去的,一律打回。

综合评价

优点:架构判断成熟,多租户与模块化的落地深度超过绝大多数同类模板;紧跟 .NET 10,没有历史包袱;前后端一体交付,节省的是真实的工时而非文档里的工时。

缺点:抽象层数偏多,新人上手曲线陡;社区规模与 ABP 不在一个量级,遇到深坑基本靠自己读源码;模块化带来的项目数量膨胀,会让 IDE 加载和 CI 时间变得不那么愉快;此外它默认了一套强主张(CQRS + MediatR + 事件驱动),如果你的团队并不认同,改造它的成本可能高于从零搭建。

一句话总结:它是一个“架构决策已经替你做了一半”的起点,适合拿来当基线,不适合拿来当黑盒。

关于

GitHub 原始描述(英文)

Production Grade Cloud-Ready .NET 10 Starter Kit (Web API + React Client) with Multitenancy Support, and Clean/Modular Architecture that saves roughly 200+ Development Hours! All Batteries Included.

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

语言占比

C#
CSS
Dockerfile
HCL
HTML
JavaScript
PowerShell
Shell
TypeScript

Release

README

⚡ FullStackHero .NET 10 Starter Kit

A production-ready, modular .NET 10 monolith + two React 19 apps — the fastest way to ship a multi-tenant SaaS.

Identity, multitenancy, billing, auditing, webhooks, files, chat, real-time, caching, jobs, storage, OpenAPI and OpenTelemetry — already wired, fully tested, and 100% yours as source (no black-box packages).

fsh CLI template .NET 10 License: MIT Docs Stars

📖 Documentation · 🚀 Get Started · 🧩 Modules · 🏗️ Architecture · 📦 Changelog


Why FullStackHero?

Most starter kits give you a login page and a TODO list. This one gives you the boring, hard parts already done right — multitenancy, auth, billing, auditing, background jobs, real-time, file storage, observability — across a clean Vertical Slice backend and two polished React 19 front-ends, orchestrated locally with one command via .NET Aspire, and deployable to Docker or AWS.

You scaffold with the fsh CLI and get the complete, detached source — every BuildingBlock, Module, and Host project with real project references. No hidden NuGet runtime, nothing to “eject” later. Own it, read it, change it.

dotnet tool install -g FullStackHero.CLI
fsh new MyApp
cd MyApp
dotnet run --project src/Host/MyApp.AppHost   # 🎉 whole stack up: API + 2 React apps + Postgres + Valkey + RustFS

Then open the Aspire dashboard at https://localhost:15888, the API + Scalar docs at https://localhost:7030/scalar, the admin app at http://localhost:5173, and the dashboard app at http://localhost:5174. Sign in with a seeded demo account (e.g. [email protected] / Password123!).


✨ What’s inside

Backend — modular monolith, vertical slices

  • .NET 10 · C# latest · Minimal APIs · Mediator (source-generated CQRS) · FluentValidation
  • EF Core 10 on PostgreSQL (Npgsql), with domain events, the specification pattern, soft-delete + audit interceptors, and tenant-isolated DbContexts.
  • JWT auth + ASP.NET Identity — issuance/refresh, roles & fine-grained permissions, rate-limited auth, password policies, sessions, impersonation.
  • Multitenancy via Finbuckle — tenant resolution, provisioning, per-tenant migrations & seeding, isolation enforced by default.
  • Cross-cutting: HybridCache on Valkey (Redis-compatible), Hangfire jobs, presigned S3 storage (RustFS locally), mailing, idempotency, quotas, rate limiting, API versioning, RFC 9457 ProblemDetails.
  • Observability: Serilog structured logging + OpenTelemetry traces/metrics/logs, health probes, security/exception auditing.
  • Docs: OpenAPI + the Scalar API reference UI.

Front-ends — two React 19 apps

  • clients/admin (operator console) and clients/dashboard (tenant app): React 19 + Vite 8 + TypeScript 6, TanStack Query v5, React Router 7, Radix + Tailwind v4 (shadcn-style), real-time via SignalR/SSE.
  • Runtime config (/config.json, no rebuild per environment), hand-written typed API client, and Playwright E2E suites.

Modules (bounded contexts)

Identity · Multitenancy · Billing · Catalog · Tickets · Chat · Files · Webhooks · Auditing · Notifications — each a runtime project plus a .Contracts project (its only public surface), boundaries enforced by architecture tests.

Cloud-native & DevOps

  • .NET Aspire orchestrates the entire stack locally with one command (Postgres + pgAdmin, Valkey + RedisInsight, RustFS, migrator, demo-seeder, API, and both React apps).
  • Docker Compose production stack (deploy/docker) and Terraform for AWS (deploy/terraform); API image published to GHCR.
  • A one-shot DbMigrator (migrations are never run at API startup), and the fsh CLI + dotnet new template for distribution.

Quality

1,600+ backend tests (xUnit, Shouldly, NSubstitute, AutoFixture, NetArchTest boundaries, Testcontainers integration) and 200+ front-end E2E tests (Playwright). Path-scoped CI for backend and frontend; warnings-as-errors.


🚀 Getting started

dotnet tool install -g FullStackHero.CLI
fsh doctor          # verify your environment (SDK, Docker, Aspire, ports)
fsh new MyApp       # interactive wizard

The wizard asks what to include (Aspire AppHost, the React apps). Non-interactive:

fsh new MyApp --non-interactive          # full stack, Postgres
fsh new MyApp --no-frontend              # backend-only
fsh new MyApp --no-aspire --no-frontend  # minimal API + migrator

Option 2 — the dotnet new template

dotnet new install FullStackHero.NET.StarterKit
dotnet new fsh -n MyApp

Option 3 — clone the repo

git clone https://github.com/fullstackhero/dotnet-starter-kit.git MyApp && cd MyApp
dotnet run --project src/Host/FSH.Starter.AppHost

Prerequisites: .NET 10 SDK · Docker (Postgres/Valkey/RustFS via Aspire) · Node 20.19+ or 22.13+ (for the React apps).

fsh commands: new · doctor · info · update · --version. Full reference → fullstackhero.net/docs/cli.


🧱 Tech stack

Backend Frontend
Runtime .NET 10 / C# latest Framework React 19 + Vite 8 + TS 6
API Minimal APIs + Mediator (CQRS) Data TanStack Query v5
Validation FluentValidation Routing React Router 7
ORM / DB EF Core 10 / PostgreSQL UI Radix + Tailwind v4 (shadcn)
Auth JWT + ASP.NET Identity Realtime SignalR · SSE
Multitenancy Finbuckle 10 Tests Playwright
Cache / Jobs Valkey · Hangfire
Storage S3 / RustFS (presigned) Infra
Docs OpenAPI + Scalar Orchestration .NET Aspire
Observability Serilog + OpenTelemetry Deploy Docker Compose · Terraform
Testing xUnit · Testcontainers · NetArchTest

🗺️ Repository layout

Path What
src/BuildingBlocks/ Shared framework libraries (Core, Persistence, Web, Caching, Eventing, Storage, Quota…)
src/Modules/{Name}/ Bounded contexts — each with a runtime project + a .Contracts project (its public API)
src/Host/FSH.Starter.Api Composition-root Web API host
src/Host/FSH.Starter.AppHost .NET Aspire orchestrator (Postgres, Valkey, RustFS, migrator, API, both React apps)
src/Host/FSH.Starter.DbMigrator One-shot migrate/seed runner (DB is not migrated at API startup)
src/Tools/CLI The fsh CLI (Spectre.Console)
clients/admin, clients/dashboard The two React apps
deploy/ Docker Compose, Terraform (AWS), Dokploy
src/Tests/ Unit, Architecture (NetArchTest), Integration (Testcontainers)

Architecture deep-dive → fullstackhero.net/docs/architecture.


☁️ Deploy

Single-host via Docker Compose:

cd deploy/docker
cp .env.example .env   # fsh new pre-generates this with strong secrets
docker compose up -d --build

AWS via Terraform (ECS Fargate + RDS + ElastiCache + S3/CloudFront) lives in deploy/terraform.

Guides → Local orchestration · Docker · AWS / Terraform · Database migrations.


🧪 Testing

dotnet test src/FSH.Starter.slnx        # backend: unit + architecture + Testcontainers integration
cd clients/admin     && npm run test:e2e # Playwright (operator app)
cd clients/dashboard && npm run test:e2e # Playwright (tenant app)

Integration tests require Docker (Testcontainers spins real Postgres). Architecture tests enforce module boundaries.


📖 Documentation

Full guides, module references, and architecture decisions live at fullstackhero.net:


🤝 Contributing

Issues and PRs are welcome — see CONTRIBUTING.md. Branch from and target main; CI runs path-scoped backend + frontend pipelines, and stable releases are cut from v* tags.

📄 License

MIT — see LICENSE. Built and maintained by Mukesh Murugan and the FullStackHero community, for teams that want to ship fast without sacrificing architectural discipline.

⭐ Star us on GitHub if this saves you time — it genuinely helps.

评论

暂无评论