Appearance
AI 辅助旧 .NET 项目现代化(V10)
老 .NET 项目现代化不是“把 TargetFramework 改掉,然后把所有 NuGet 升到最新”。真正需要保护的是已经在现场工作的行为、设备兼容、部署环境和历史数据。
V10 推荐:
text
Read-Only Assessment
→ known-good baseline
→ 选择一个 migration slice
→ 最小修改
→ 同场景验证
→ 再决定下一 slice不是所有项目都需要走完全相同的阶段,也不要求现代化时顺便重写 UI、协议、线程和数据层。
1. 先判断“为什么要现代化”
目标不同,改动范围完全不同:
| 目标 | 可能只需要什么 |
|---|---|
| 旧项目难构建 | 固定 SDK/依赖/构建说明 |
| 某第三方库已不可维护 | 单独替换依赖 |
| 只想改善可测试性 | 给关键 seam 补 Fake/Replay/测试 |
| 只想整理结构 | 小范围职责收敛,不升级框架 |
| 必须迁移到现代 .NET | 目标框架 + 依赖 + 部署 + 行为兼容 |
| 准备长期产品化 | 在稳定基线之上分批现代化 |
不要把“现代化”自动解释成“整个项目升级到最新 .NET”。
2. 第一阶段是 Read-Only Assessment,不是立刻改代码
先确认事实:
text
Solution / csproj
TargetFramework
NuGet / 本地 DLL / COM
第三方 UI 控件
驱动 / VISA / SDK
串口/TCP/协议
数据库 / 文件格式
部署方式
运行机器与 OS
构建命令
已有测试 / Fake / Replay同时确定一个可用的 known-good:
- 当前现场安装包;
- 已知稳定 Git commit/tag;
- 可重复构建的旧分支;
- 正常日志/配置快照。
没有 known-good,就很难判断迁移后的差异到底来自现代化还是原本就存在。
Assessment Prompt
text
$host-computer-dev
只做旧 .NET 项目现代化 Assessment,先不要改代码或升级包。
现代化目标:
【例如:评估迁移 .NET 8 / 只替换旧图表库 / 先建立可重复构建】
请从仓库自行确认当前框架、依赖、启动入口、构建/部署、第三方控件、设备通信、数据兼容和已有测试资产。
输出:
1. known-good 基线;
2. 当前兼容约束;
3. 高风险依赖;
4. 可以独立迁移的 slices;
5. 真正需要我决定的 Blocking Decisions。3. 旧项目最值得先看的是兼容边界
| 类型 | 常见风险 |
|---|---|
| .NET Framework WinForms | Designer、GDI/ActiveX、第三方控件、老配置机制 |
| .NET Framework WPF | XAML 资源、Binding、旧 MVVM/主题库、设计时依赖 |
| 混合类库 | 目标框架不一致、binding redirect、包版本冲突 |
| 设备控制 | 驱动版本、x86/x64、COM/VISA、厂商 SDK、Session 行为 |
| 数据 | 旧数据库、CSV/二进制文件、序列化字段、历史读取 |
| 部署 | 工控机 OS、.NET Runtime、注册表、权限、安装器 |
这些是迁移事实,不应靠 AI 按“现代 .NET 常见做法”自动补答案。
4. 用 Migration Slice 代替固定六阶段
一个 slice 应满足:
text
一个明确目标
+ 可描述的 change surface
+ 独立验证方式
+ 可回退例如:
text
Slice A: 建立旧版可重复构建
Slice B: 替换一个已经停更的日志库
Slice C: 给协议 parser 建 Replay seam
Slice D: 将某个独立类库改为 SDK-style
Slice E: 主程序迁移目标框架
Slice F: 安装与部署适配不是每个项目都需要 A→F 全部执行。当前目标完成后可以停止。
5. 不要为了迁移先强制 TDD
老项目可能没有测试 seam,也可能和真实硬件深度耦合。
优先使用当前最便宜、最稳定的行为基线:
text
existing focused test
→ Fake / Simulation
→ Captured Replay
→ known-good log / output
→ minimal harness
→ 受控人工 smoke
→ 必要真机 HITL有稳定 seam 时补测试很有价值;没有 seam 时,不要为了“迁移前必须覆盖测试”先做一轮大架构重构。
6. 框架/依赖迁移时坚持“一批一个变量”
不建议:
text
.NET Framework → .NET 8
+ 换 UI 框架
+ 升全部 NuGet
+ 重写通信
+ 改数据库
+ 改线程模型更容易验证的是:
text
固定 baseline
→ 一组相关依赖/一个目标框架变化
→ build
→ focused behavior
→ 比较 known-good如果迁移失败,要能知道是哪一个 slice 引入的差异。
7. 默认保持的 NonGoals
除非现代化目标明确要求,否则默认不改变:
- 通信协议语义;
- 设备动作时序;
- AlarmOnly / InterlockFault 后果;
- 数据库 Schema 和历史文件格式;
- 操作员主流程;
- 设备关键参数;
- 真机安全联锁。
如果其中任何一项必须变化,它不再只是“技术升级”,需要单独 Behavior/Domain/Compatibility 设计和验证。
8. 设备与 Session 是迁移风险,不是最后才看的问题
现代化常见隐蔽回归:
- x86 → x64 后厂商 DLL 不可用;
- 新 async 结构导致 Stop 后旧任务仍存活;
- 新驱动改变 timeout/取消行为;
- 恢复路径无意建立第二 SCPI/VISA Session;
- 新 Runtime/部署目录改变配置读取;
- SDK 包升级改变错误码或线程约束。
涉及真实仪器时,诊断默认复用现有 Device Session Owner;不要为了迁移验证偷偷开第二个互斥设备会话。
9. 验证按 slice 风险选 V0–V4
| 迁移 slice | 常见验证 |
|---|---|
| 文档/构建说明 | V0 |
| 局部普通依赖/项目格式 | V1/V2 |
| 数据/通信/配置兼容 | V2 |
| 生命周期、状态机、Stop/恢复 | V3 |
| 主框架迁移、部署、广泛依赖兼容 | V4 checkpoint |
协议验证按实际协议模型走。自定义字节流才检查相应 framing/CRC;SCPI、Modbus、厂商 SDK 按各自命令、状态、错误和生命周期验证。
10. 真机和现场状态要单独记录
软件侧通过:
text
build
focused tests
Fake / Replay
WorkflowSmoke并不等于现场已经验收。
如果该 slice 最终需要真实设备,但当前没有执行:
text
VerificationState: HardwarePending如果是 SDK、权限、构建机等软件环境阻塞:
text
VerificationState: EnvironmentBlocked不要把二者混用,也不要为了让迁移“全绿”自动执行高压、运动、阀门等危险动作。
11. 迁移结果建议怎么记录
text
Slice:
Target:
KnownGood:
Changed:
CompatibilityConstraints:
VerificationLevel:
VerificationState:
Evidence:
ResidualRisk:
Rollback:
NextSlice: OptionalNextSlice 是可选的。当前目标已经达成时,不为了“现代化完整”继续扩大范围。
12. 迁移计划 Prompt
text
$host-computer-dev
根据已经完成的 Read-Only Assessment,为这个旧 .NET 项目选择下一批最小 migration slices。
约束:
- 每个 slice 可独立回退;
- 不改变未授权的设备/协议/业务语义;
- 优先复用现有测试/Fake/Replay/known-good;
- 不为了补测试先做大重构;
- 主框架/广泛兼容变化才进入 V4。
请给:
1. 推荐顺序和理由;
2. 每个 slice 的 change surface;
3. Verification Level;
4. 回退点;
5. 当前可以明确不做的内容。13. AI 能帮的高价值事情
- 建立旧项目依赖和兼容地图;
- 比较 csproj/NuGet/Runtime 差异;
- 找迁移 hot spot;
- 识别现有稳定 seam;
- 生成 Fake/Replay/harness;
- 比较 known-good 行为;
- 给 migration Diff 做 Review;
- 整理部署和兼容证据。
完成判定
一个现代化任务可以在“目标 slice 已完成”时结束,不要求一次完成全项目改造。
完成时应能说明:
- 本次目标和 NonGoals;
- known-good;
- 实际 Diff;
- 兼容性结果;
- Verification Level / State;
- 仍为
HardwarePending或Unverified的部分; - 可回退位置。