SeatFlow 9 个项目目录结构、依赖关系、csproj 关键设置和 NuGet 管理
本页目录
全部文档
项目结构
解决方案文件
SeatFlow 使用新版 XML 格式的解决方案文件 SeatFlow.slnx(.slnx 格式,而非传统 .sln)。所有 9 个项目均在此解决方案中管理。
SeatFlow.slnx
├── SeatFlow.Core/ → 领域核心
├── SeatFlow.Application/ → 应用编排层
├── SeatFlow.Infrastructure/ → 基础设施实现
├── SeatFlow.Presentation.Avalonia/ → 共享 UI 类库(桌面 + 浏览器)
├── SeatFlow.Desktop/ → 桌面启动壳
├── SeatFlow.Browser/ → 浏览器 WASM 启动壳
├── SeatFlow.Core.Tests/ → 核心测试
├── SeatFlow.Application.Tests/ → 应用层测试
└── SeatFlow.Infrastructure.Tests/ → 基础设施测试
项目列表与用途
| 项目 | 类型 | 用途 |
|---|---|---|
SeatFlow.Core |
类库 | 领域实体、策略接口和 7 条内置策略、领域服务、工作区、数据提供者接口、存储抽象 ILocalDataStore、工具类 |
SeatFlow.Application |
类库 | 外观接口/实现、策略管道执行器、命令模式、DI 扩展方法 |
SeatFlow.Infrastructure |
类库 | CSV/XLSX/JSON 数据提供者、导出器、布局构建器、JSON 仓库、文件迁移系统、序列化、SeatSets 服务、平台存储实现 |
SeatFlow.Presentation.Avalonia |
类库 | 共享 UI 层(net10.0;net10.0-browser),MVVM、导航、主题、平台服务接口 |
SeatFlow.Desktop |
桌面应用 | 桌面启动壳。输出 EXE 名为 SeatFlow.exe,含 Velopack 自动更新、Watchdog、单实例 |
SeatFlow.Browser |
浏览器应用 | 浏览器启动壳(net10.0-browser)。WASM 静态站,发布产物为 wwwroot/ |
SeatFlow.Core.Tests |
测试 (xUnit v3) | Core 层单元测试 |
SeatFlow.Application.Tests |
测试 (xUnit v3) | Application 层单元测试 |
SeatFlow.Infrastructure.Tests |
测试 (xUnit v3) | Infrastructure 层单元测试 |
项目依赖图
SeatFlow.Desktop ──┐ SeatFlow.Browser ──┐
▼ ▼
Presentation.Avalonia ───────────────┘
│
▼
Application
│
┌──────┴──────┐
▼ ▼
Core Infrastructure
严格的分层依赖:
SeatFlow.Desktop/SeatFlow.Browser→Presentation.AvaloniaPresentation.Avalonia→ApplicationApplication→Core、Infrastructure- 无循环依赖,下层不引用上层
关键目录和文件
每个项目内的典型目录结构
SeatFlow.Core/
├── Models/ ← 领域实体 (Student, Seat, LayoutDefinition 等)
├── Strategies/
│ ├── Interfaces/ ← ISeatingStrategy, IDependentSeatingStrategy
│ ├── Manifests/ ← 策略 manifest JSON 文件(声明式配置)
│ ├── FixedSeatStrategy.cs
│ ├── FrontRowRotationStrategy.cs
│ ├── RandomFillStrategy.cs
│ ├── DefragStrategy.cs
│ ├── DeskMateStrategy.cs
│ ├── GenderRestrictedSeatStrategy.cs
│ └── NoRepeatDeskMateStrategy.cs
├── DomainServices/ ← 领域服务
│ ├── ObstacleProcessor.cs
│ ├── SeatGeometryHelper.cs
│ ├── StrategyManifestProvider.cs
│ └── SeatAdjacencyHelper.cs
├── Workspace/ ← SeatingWorkspace
├── Utilities/ ← CircularHistory<T>, AttributeBag
└── Abstractions/ ← 数据提供者接口, ILocalDataStore
SeatFlow.Application/
├── IApplicationFacade.cs ← 外观接口
├── ApplicationFacade.cs ← 外观实现
├── StrategyExecutionPipeline.cs ← 管道执行器
├── Commands/ ← IUndoableCommand, CommandHistory
└── ServiceCollectionExtensions.cs ← DI 注册
SeatFlow.Infrastructure/
├── Providers/ ← Csv/Xlsx/Json/Composite/InMemory 数据提供者
├── Writers/ ← Json/Csv/Xlsx 数据写入器
├── Exporters/ ← Excel/Csv/Pdf/Image 导出器
├── LayoutBuilders/ ← Grid/Polar/Freeform 布局构建器
├── Repositories/ ← JsonVenue/JsonAppSettings/StrategyConfig/等
├── FileSystemDataStore.cs ← 桌面端 ILocalDataStore 实现
├── IndexedDbDataStore.browser.cs ← 浏览器端 ILocalDataStore 实现(条件编译)
├── Migration/ ← FileMigrationService, IFileMigrator
│ ├── file_versions.json ← 各文件类型当前版本号
│ ├── Migrators/ ← 版本迁移器实现
│ └── Seatsets/ ← 数据包打包/解包
└── Serialization/ ← SeatJsonConverter 等
SeatFlow.Presentation.Avalonia/
├── App.axaml / App.axaml.cs ← 应用生命周期与启动序列
├── MainView.axaml / MainView.axaml.cs ← 共享 UI 外壳(桌面与浏览器共用)
├── ViewModels/ ← 9 个页面 ViewModel
├── Views/ ← 对应 9 个页面的 View
├── Services/ ← 导航、对话框、文件等平台服务接口与共享实现
├── Lang/ ← .resx 国际化资源文件
├── Behaviors/ ← CanvasZoomPan, ZoomOnScroll, ChineseInputNormalizer
├── Converters/ ← BoolConverters, ValueConverters
├── Controls/ ← 自定义控件
└── Data/ ← 嵌入资源 (about.json, onboarding_config.json, page_navigation.json)
SeatFlow.Desktop/
├── 主窗口 ← MainWindow : Window,承载共享 MainView
├── 桌面入口 ← Velopack 更新钩子、Watchdog、单实例
└── 平台服务注册 ← FileSystemDataStore、桌面文件/对话框服务
SeatFlow.Browser/
├── 浏览器入口 ← ISingleViewApplicationLifetime.MainView
├── 平台服务 ← WebDialogService、WebFileService、BrowserConsoleLoggerProvider
└── wwwroot/js/ ← interop.js(sf.idb)、files.js(sf.files)
NuGet 包管理
不使用 Directory.Build.props 或 Directory.Packages.props。包版本直接在每个 .csproj 中管理。这确保了每个项目的依赖版本显式可见。
主要 NuGet 包
| 包名 | 用于 |
|---|---|
Avalonia / Avalonia.Desktop / Avalonia.Browser |
跨平台 UI 框架(桌面 / 浏览器) |
CommunityToolkit.Mvvm |
MVVM 源码生成器 |
Serilog / Serilog.Sinks.File |
结构化日志 |
Microsoft.Extensions.DependencyInjection |
DI 容器 |
Microsoft.Extensions.Logging.ILogger<T> |
日志抽象 |
EPPlus |
XLSX 文件读写(桌面与浏览器) |
QuestPDF |
PDF 导出(仅桌面) |
xunit.v3 / FluentAssertions / NSubstitute |
测试栈 |
csproj 关键设置
共享类库的多目标框架 (SeatFlow.Presentation.Avalonia.csproj)
共享 UI 类库同时面向桌面与浏览器:
<TargetFrameworks>net10.0;net10.0-browser</TargetFrameworks>
<!-- 编译绑定默认启用 -->
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<!-- Designer.cs 不存在时跳过编译(首次克隆时) -->
<Compile Remove="Lang\Resources.Designer.cs"
Condition="!Exists('Lang\Resources.Designer.cs')" />
浏览器专属资源(如内嵌 CJK 字体)通过 MSBuild 条件限定到 net10.0-browser 目标。
桌面壳项目设置 (SeatFlow.Desktop.csproj)
<!-- 输出 EXE 名称,而非项目名称 -->
<AssemblyName>SeatFlow</AssemblyName>
<!-- Windows DPI 感知 -->
<ApplicationManifest>app.manifest</ApplicationManifest>
<!-- 抑制 DI 构造函数注入警告 -->
<NoWarn>AVLN3001</NoWarn>
<!-- 确定性构建 -->
<Deterministic>true</Deterministic>
<PathMap>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)'))=./</PathMap>
Git 提交哈希注入
MSBuild 目标 GenerateGitCommit 在每次构建前运行 git rev-parse --short HEAD,生成 GitCommit.g.cs(位于 $(IntermediateOutputPath)Generated\),提供 GitCommit.Hash 常量。git 不可用时回退到 "unknown-commit-id"。该文件不提交到版本控制。
dotnet 工具
仓库根目录的 dotnet-tools.json 中安装了 avaloniaui.developertools (avdt),仅在桌面环境下可用,在无头环境中跳过。
浏览器端构建需要 WASM 工作负载:dotnet workload install wasm-tools。