跳转到主内容

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.Avalonia
  • Presentation.Avalonia → Application
  • Application → 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。