BuildingBlocks
:::info 性质说明
BuildingBlocks 是本仓库内部的共享项目集合(位于 src/BuildingBlocks/,通过 ProjectReference 被各业务模块引用),并非独立发布的 NuGet 包。它的能力建立在 IGeekFan.* 框架 NuGet 包(IGeekFan.FreeKit / IGeekFan.FreeKit.Extras 等)之上,是对"模块化单体 + DDD"场景的二次封装与约定——把分散在各处的基础设施(认证、缓存、异常、启动装配、脚手架)收敛成一套可直接复用、风格统一的构建块。
:::
它解决什么问题
在模块化单体里,每个业务模块(CmsKit / Platform / Identity / Member…)都会重复遇到同一组横切问题:
- 启动太繁琐:Autofac、Serilog、FreeSql、Swagger、认证、CAP、本地化……逐个
AddXxx既冗长又容易配错顺序。 - 约定不统一:Controller 基类、应用/领域服务基类、统一响应、统一异常、权限模型,如果每个模块各写一套,协作成本极高。
- 接入 SSO 成本高:作为 OpenIddict 的客户端验证 Token、对接单点登录,需要重复搬运配置与中间件。
- CRUD 样板代码多:每个实体都要手写 Controller / Service / Dto / 权限,结构高度雷同。
BuildingBlocks 就是用来消除这些重复的:下层用 Infrastructure 沉淀约定,中层用 Web 做一站式启动装配,跨系统用 Auth.Client 做 SSO 验证,开发期用 CLI 生成样板代码。
包全景
| 包 | 层级 | 一句话定位 | 详情 |
|---|---|---|---|
IGeekFan.FreeKit.Infrastructure | 基础能力 | Controller/DTO 基类、应用/领域服务基类、认证授权、缓存、异常、加解密、过滤器等"全家桶"约定 | infrastructure.md |
IGeekFan.FreeKit.Web | 启动装配 | UseFreeKit() 一行式把全部基础设施正确接起来(Autofac/Serilog/模块扫描/认证/Swagger/CAP…) | web.md |
IGeekFan.FreeKit.Auth.Client | 认证客户端 | 让任意 ASP.NET Core 应用作为 OpenIddict 客户端验证 Token、对接 SSO | auth-client.md |
IGeekFan.FreeKit.CLI | 开发工具 | freekit scaffold 基于 Scriban 模板按实体生成全套 CRUD 代码 | cli.md |
关系说明:
Infrastructure是所有模块共享的基础;Web与Auth.Client都建立在它之上;CLI是开发期工具,生成的代码遵循Infrastructure/Web的约定。CLI不在运行时依赖链上。
包详解
1. Infrastructure —— 约定与基础能力
它是什么:最底层的构建块,提供贯穿各层的基类与横切能力,让模块"开箱即有一套统一规范"。
关键能力:
- Controller 基类:
KitApiControllerBase(无认证)、FreeKitController([Authorize]基类,多数控制器继承)。 - 应用服务基类:
ApplicationService(懒加载注入CurrentUser/UnitOfWorkManager/Mediator/CapPublisher/Logger/AuthorizationService/PermissionStore);CrudAppService<TEntity, TDto, TListDto, TKey, TQuery, TCreate, TUpdate>自动获得GetList/Get/Create/Update/Delete。 - 领域服务基类:
DomainService、IDomainEventDispatcher(分发并清空聚合根领域事件)。 - 认证授权:
CookieJwtBearerHandler(Query/Header/Cookie 三种 Token 来源)、KitAuthorize特性、IPermissionStore、AuthMode(Jwt / OpenIddict)。 - 缓存:
ICacheService+CacheShell+[Cacheable]AOP 缓存(Redis / Memory 双策略)。 - 异常体系:
BusinessException/EntityNotFoundException/BadRequestException等 +Guard+ApiResponse/ResponseCode统一响应。 - 工具:
AESUtil/DESUtil/SM4Util/Md5Util/ToolHelper(Base64)/MaskHelper(脱敏)。 - 中间件/过滤器:
EncryptionMiddleware、BasicAuth(保护 Swagger)、IP 限流、SensitiveDataAttribute(脱敏)、RecaptchaVerifyActionFilter。 - DTO 与扩展:
ApiResponse、PageQuery、ISortedResultRequest、FreeSql/内存分页、CAP 事务、IFileProvider扩展。
最小示例(统一响应 + 基类):
[ApiController]
[Route("api/[controller]")]
public class ArticleController : FreeKitController
{
[HttpGet]
public async Task<IActionResult> GetList([FromQuery] ArticleListQuery query)
{
var list = await _service.GetListAsync(query);
return Ok(ApiResponse.Ok(list));
}
}
2. Web —— 一站式启动装配
它是什么:IGeekFan.FreeKit.Web 是 ASP.NET Core 的启动层。它把下层所有能力(数据访问、认证、缓存、Swagger、分布式事件、本地化…)用一行 UseFreeKit(...) 正确装配起来,避免手写冗长的 AddXxx 链与易错的顺序。
关键能力:模块化启动(IModuleStartup 按 moduleTypeMap 自动扫描注册)、Autofac 容器、Serilog 结构化日志、Kestrel 大请求体(默认 1GB)、JWT/OpenIddict 双认证 + 7 种第三方 OAuth、Swagger/RapiDoc(多项目文档 + 枚举描述过滤器)、Redis/Memory 缓存、CAP + MediatR 分布式事件、IP2Region 地理定位、IP 限流、健康检查、本地化、响应加密、gRPC、定时任务。
最小示例:
var builder = WebApplication.CreateBuilder(args);
// 一行完成:模块注册 + Autofac + Serilog + 全部可选功能
builder.UseFreeKit(
moduleTypeMap: new Dictionary<string, Type>
{
["identity"] = typeof(IdentityModuleStartup),
["cms"] = typeof(CmsKitModuleStartup),
["plat"] = typeof(PlatformModuleStartup)
},
extraAssemblies: new[] { typeof(Program).Assembly }
);
var app = builder.Build();
app.Run();
所有可选功能由 FreeKitDIOptions 驱动(默认全开,按需关闭,例如 options.EnableFeishu = false)。详见 web.md 的"服务注册与选项"章节。
3. Auth.Client —— 对接 OpenIddict 的 SSO 验证
它是什么:当你的应用不是认证中心、而是要把自己接入已有的 OpenIddict 认证中心做单点登录时使用的客户端库。它封装了 Token 验证、Scope 校验与自动注册。
最小示例:
// Program.cs
builder.Services.AddFreeKitValidation();
// app 管道
app.UseAuthentication();
app.UseAuthorization();
{
"OpenIddictValidation": {
"Authority": "https://auth.example.com",
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret",
"RequireHttpsMetadata": false
}
}
详见 auth-client.md(含工作原理时序图、多应用/微服务间调用示例与故障排查)。
4. CLI —— 代码脚手架
它是什么:开发期 dotnet 全局工具,基于 Scriban 模板按实体文件生成全套 CRUD 代码(Controller / Application / Domain / Models / Contracts),支持 cmskit 与 platform 两种风格,也可自定义模板。
最小示例:
freekit scaffold ^
--profile cmskit ^
--group Content ^
--base-directory src\Services\CmsKit\FreeKit.CmsKit ^
--project-name FreeKit.CmsKit ^
--entity-file-path Models\Article.cs ^
--output-directory D:\code-scaffolding
详见 cli.md(命令参数、Profile、生成文件清单、模板变量与自定义模板)。
它们如何协作(典型 Host 组合)
一个业务 Host 通常是这样把构建块拼起来的:
// Program.cs
var builder = WebApplication.CreateBuilder(args);
// Web 一站式启动:内部已引用 Infrastructure 的约定(Controller 基类、CrudAppService、缓存、异常等)
builder.UseFreeKit(
moduleTypeMap: E.Modules,
extraAssemblies: new[] { typeof(Program).Assembly }
);
// 若该 Host 需要作为 OpenIddict 客户端接入 SSO,再叠加 Auth.Client
builder.Services.AddFreeKitValidation();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.Run();
<!-- 业务模块通过 ProjectReference 引用构建块 -->
<ProjectReference Include="..\..\BuildingBlocks\IGeekFan.FreeKit.Infrastructure\IGeekFan.FreeKit.Infrastructure.csproj" />
<ProjectReference Include="..\..\BuildingBlocks\IGeekFan.FreeKit.Web\IGeekFan.FreeKit.Web.csproj" />
开发期用 CLI 生成样板后,再按上述方式装配即可。
我该用哪个?
| 你的场景 | 用哪个构建块 |
|---|---|
| 写一个新的 Web API 模块,想尽量少写启动/约定样板 | Web + Infrastructure(UseFreeKit 一站式) |
| 需要统一的 Controller/DTO/异常/缓存/加解密约定 | Infrastructure |
| 应用要作为 OpenIddict 客户端做单点登录(验证 Token) | Auth.Client |
| 想根据实体快速生成全套 CRUD 代码、统一风格 | CLI |
| 只是用 FreeSql 做数据访问、不想要整套 Web 约定 | 直接用 IGeekFan.FreeKit.Extras(见 Extras),无需引入本目录 |
使用方式
各业务模块通过项目引用使用这些构建块(它们不是 NuGet 包):
<ProjectReference Include="..\..\BuildingBlocks\IGeekFan.FreeKit.Infrastructure\IGeekFan.FreeKit.Infrastructure.csproj" />
<ProjectReference Include="..\..\BuildingBlocks\IGeekFan.FreeKit.Web\IGeekFan.FreeKit.Web.csproj" />
若你的项目不在本仓库内、无法
ProjectReference,则需要将这些构建块先打包为 NuGet(CLI 工具已支持dotnet pack),再dotnet add package引用——但目前仓库内统一以源码引用方式共享。
相关文档
- 基础设施 Infrastructure
- Web 启动层
- 认证客户端 Auth.Client
- CLI 脚手架
- Extras 扩展包 — 更底层的 FreeSql/CurrentUser/事务/多租户能力
- 共享功能
- 基础设施分层