恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
RackPeek源码架构深度解析:一套.NET 10领域代码如何同时驱动CLI与Blazor Web UI
首页
资讯中心
/
RackPeek源码架构深度解析:一套.NET 10领域代码如何同时驱动CLI与Blazor Web UI
RackPeek源码架构深度解析:一套.NET 10领域代码如何同时驱动CLI与Blazor Web UI
发布时间:2026/10/11 18:53:15
【免费下载链接】RackPeekCLI tool to discover, manage, and document your IT infrastructure and home lab.项目地址https://gitcode.com/gh_mirrors/ra/RackPeek点击查看免费下载RackPeek 是一款面向家庭实验室Home Lab与小型 IT 基础设施的开源文档管理工具它用同一套 .NET 10 领域代码同时驱动命令行工具CLI与 Blazor Web UI让你可以用 YAML 文件追踪服务器、交换机、防火墙等硬件及其关系。这篇文章带你拆解 RackPeek 的源码架构从解决方案布局、领域层设计到一条命令在终端和浏览器里都能跑的关键机制。一、解决方案全景7个项目各司其职打开 RackPeek.sln 你会发现整个方案由 7 个项目组成依赖关系清晰、方向单一项目角色关键技术RackPeek.Domain/核心领域层资源模型、UseCase、YAML 持久化、Git 集成YamlDotNet、LibGit2SharpShared.Rcl/共享层CLI 命令 Blazor 组件 控制台模拟器Spectre.Console、Razor Class LibraryRackPeek/CLI 可执行程序rpk命令Spectre.Console.CliRackPeek.Web/Blazor Server Web UI Inventory APIASP.NET CoreRackPeek.Web.Viewer/Blazor WASM 纯浏览器只读查看器WebAssemblyTests/单元/集成测试含 CLI 工作流测试xunitTests.E2e/Playwright 端到端测试Playwright、Testcontainers依赖方向只有两条两个入口CLI / Web→ Shared.Rcl → RackPeek.Domain。领域层不依赖任何 UI 技术这是一套代码驱动两个界面的前提。二、领域层拆解RackPeek.Domain 是单一事实来源2.1 领域模型Resource 家族 子资源所有受管对象都继承自 Resource 基类派生出 10 种资源类型服务器、交换机、路由器、防火墙、AP、UPS、台式机、笔记本、系统、服务按目录组织在RackPeek.Domain/Resources/下。硬件类资源还能挂接子资源——CPU、内存、磁盘、GPU、网卡定义在 SubResources/ 目录中。Resource基类Name/Tags/Labels/RunsOn ├─ Hardware ──► Server / Switch / Router / Firewall ... │ ├─ Cpu / Ram / Drive / Gpu / Nic / Port ├─ SystemResource虚拟机、Docker 容器等逻辑系统 └─ Service运行在系统上的服务含子网/IP 信息资源之间的依赖通过RunsOn运行于字段表达物理线缆连接则由独立的 Connection 模型记录哪个设备的哪个端口接到了哪。2.2 UseCase 模式业务逻辑的归属地每个业务操作都是一个独立的 UseCase 类例如添加资源的 AddResourceUseCase名称规范化 → 重名校验抛ConflictException→ 父资源合法性校验 → 落库。校验规则集中在领域层而不是散落在 CLI 或 UI 里两个入口自然共享同一套行为。特别值得关注的是泛型 UseCase设计// RackPeek.Domain/UseCases/AddResourceUseCase.cs public interface IAddResourceUseCaseT : IResourceUseCaseT where T : Resource { Task ExecuteAsync(string name, Liststring? runsOn null); }一个AddResourceUseCaseT就覆盖了全部 10 种资源类型——Server、Switch、Firewall……都复用同一份实现靠T参数实例化具体类型。2.3 YAML 持久化单文件即数据库RackPeek 没有使用传统数据库所有状态都保存在一个config.yaml文件里。核心实现在 YamlResourceCollection.cs内存加载启动时一次性读入ResourceCollection单例所有查询走内存速度快写时落盘每次增删改都在SemaphoreSlim文件锁保护下全量回写避免并发损坏Schema 版本迁移文件内记录version字段配合 RackPeekConfigMigrationDeserializer 完成 v1 → v2 → v3 的平滑升级迁移前自动备份.bakSchema 校验配套 JSON Schemaschemas/v3/schema.v3.json保证文件格式可被第三方工具校验。三、共享层 Shared.Rcl架构最精彩的部分3.1 反射驱动的自动注册Shared.Rcl/ServiceCollectionExtensions.cs 中的AddCommands()不用手写注册而是反射扫描程序集里所有AsyncCommand派生类自动注册为 Scoped 服务。新增一个 CLI 命令 新建一个类零注册成本。领域层的 AddUseCases() 同样用反射扫描所有IUseCase实现。3.2 命令树的唯一构建者CliBootstrapCliBootstrap.BuildApp() 用 Spectre.Console 的分支 DSL 声明了整个命令树——rpk servers add、rpk switches port set、rpk graph topology……全部集中在这一个方法里。这意味着命令树只定义一次CLI 和 Web UI 共用。3.3 ConsoleEmulator在浏览器里跑CLI这是一套代码两个界面的点睛之笔。ConsoleEmulator 实现了领域层定义的IConsoleEmulator接口构造时注入同一个 DI 容器用CliBootstrap.BuildApp()构建与真实 CLI完全相同的命令树Execute(input)用 Spectre.Console.Testing 的TestConsole替换真实控制台把用户输入的命令交给CommandApp.RunAsync执行捕获终端输出含 ANSI 样式回传给 Blazor 组件渲染成网页终端。Blazor 端的 ConsoleEmulatorComponent.razor 负责键盘、光标、命令历史的交互。Web 页面上的rpk提示符不是仿真的它执行的就是真正的领域层命令——输出结果与你在 Docker 终端里敲的命令逐字一致。3.4 命令 → UseCase 的标准调用链以 ServerAddCommand 为例共享层命令的实现模式统一用户输入终端或网页 → Spectre Command 解析参数Settings 类 → 从 DI 容器解析 IAddResourceUseCaseServer → 调用 useCase.ExecuteAsync(name) → YamlResourceCollection 加锁回写 config.yaml → 返回 ANSI 结果UI 相关的 Razor 页面服务器列表、设备卡片等则直接注入 UseCase/仓储做富交互展示例如 ServersListPage.razor。两条路径殊途同归都只碰领域层。四、三个入口同一套核心4.1 CLI 入口Docker 部署的主形态RackPeek/Program.cs 只有 36 行读配置 →CliBootstrap.RegisterInternals()完成 DI 注册含预加载 YAML→CommandApp.RunAsync(args)。CLI 是薄壳所有逻辑都在下面两层。4.2 Blazor Server Web UI 入口RackPeek.Web/Program.cs 注册的是同一组扩展方法AddYamlRepos()、AddUseCases()、AddCommands()并额外注册了IConsoleEmulator。同时它暴露了一个 REST 端点 POST /api/inventory供外部工具通过 API Key 上传/合并 YAML——这得益于领域层Merge()方法本身就支持多种合并策略。4.3 Blazor WASM 查看器依赖注入换掉文件系统最精妙的适配点在持久化抽象。领域层只依赖 3 个方法的接口 ITextFileStoreExists / Read / WriteCLI 与 Web Server 注入 PhysicalTextFileStore读写磁盘文件WASM 查看器WasmTextFileStore通过 JS Interop 读写浏览器 localStorage存储为空时再从wwwroot/config/config.yaml走 HTTP 拉取兜底。一行 DI 注册的差异就让整套领域代码跑进了纯浏览器环境——WASM 版因此能作为零后端的静态页面嵌入博客或文档站点。五、值得借鉴的 4 个架构实践 薄入口 厚领域两个 Program.cs 都不含业务逻辑领域层可被 CLI、Web、WASM、测试任意复用Null Object 模式未配置GIT_TOKEN时注入 NullGitRepository而不是到处写if (gitEnabled)判断Git 功能Git 集成文档有说明变成可选插件泛型消除重复IAddResourceUseCaseT、TagAddCommandT等让 10 种资源共用实现新增资源类型的边际成本极低测试与架构同构Tests/ 的 CLI 工作流测试直接复用ConsoleEmulator执行真实命令并断言输出E2E 层则用 Playwright 驱动真实浏览器两层测试都验证的是同一套领域行为。六、源码阅读路线建议 如果你是 .NET 新手想读懂这个项目推荐按此顺序阅读RackPeek/Program.cs36 行理解启动流程Shared.Rcl/CliBootstrap.cs命令树全景顺便就是命令手册RackPeek.Domain/Resources/Resource.cs与任一具体资源如 Server.csRackPeek.Domain/UseCases/任选 2-3 个 UseCaseRackPeek.Domain/Persistence/Yaml/YamlResourceCollection.cs持久化与版本迁移docs/development/dev-cheat-sheet.md与 docs/development/contribution-guidelines.md 了解构建与贡献规范。结语RackPeek 的架构回答了一个很好的问题如何让终端命令与网页界面永远不行为漂移答案是把业务逻辑全部沉到领域层的 UseCase 中让 Spectre 命令与 Blazor 组件都只是不同壳子的同一副引擎再用IConsoleEmulatorITextFileStore两个小抽象抹平运行时差异。对任何想同时做 CLI 和 Web 的 .NET 开发者来说这套薄壳 厚领域 反射注册 存储抽象的组合都值得直接抄作业。赞分享【免费下载链接】RackPeekCLI tool to discover, manage, and document your IT infrastructure and home lab.项目地址https://gitcode.com/gh_mirrors/ra/RackPeek点击查看免费下载相关推荐Readest 系统架构深度解析一套 TypeScript/React 代码库如何驱动桌面、移动与 Web 三端Readest 系统架构深度解析一套 TypeScript/React 代码库如何驱动桌面、移动与 Web 三端 导读 本文以 apps/readest ap桌面应用跨平台前端推荐《实战领域驱动设计与.NET Core》开源代码库推荐《实战领域驱动设计与.NET Core》开源代码库 在这个日益复杂的世界中软件开发人员正面临着如何处理复杂业务需求的挑战。《实战领域驱动设计与.NET后端软件架构PlayIntegrityFix完整指南5步解决Android设备Google Play认证问题PlayIntegrityFix完整指南5步解决Android设备Google Play认证问题 你是否遇到过这样的困扰打开Google Play商店时看应用安全系统编程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考