热重载测试通过。

步骤 结果
桥接 ping 正常
编译 → staging 成功
部署 slot 20260623093716985 成功
reload_plugin 热重载完成
重载后 ping 正常

当前加载core\20260623093716985\sw_plugin.dll(core 构建时间 09:37:08

Loader 壳未变(09:21:21),只换了 core DLL,无需重启 SW

日常改代码后可按这个流程:

dotnet build e:\code\code\csharp_sw\sw_plugin\sw_plugin.csproj -c Debug -o e:\code\code\csharp_sw\sw_plugin\bin\hotreload_staging
# 部署 slot + reload_plugin(或跑 reload-sw-plugin.ps1)

需要的话可以继续测方程式修改后的上级装配体重建。


“Loader 壳插件 + 动态 LoadFrom 业务 DLL” 是一种在软件开发(特别是 AutoCAD 二次开发、插件化架构或热更新场景)中常用的技术架构模式。它的核心目的是解决业务代码更新时需要重启主程序的痛点,实现免重启调试或热更新

简单来说,这是一种**“将命令注册与业务逻辑分离”**的设计思路。

1. 核心角色解析

  • Loader 壳插件(加载器)
    这是一个非常稳定、极少修改的“壳子”DLL。它被主程序(如 AutoCAD)加载并注册命令。它的唯一职责是作为一个“桥梁”或“入口”,负责触发和引导真正的业务代码。
  • 业务 DLL(业务逻辑)
    这是包含你实际核心功能代码的 DLL。在开发过程中,你会频繁修改这部分代码。
  • 动态 LoadFrom
    这是 .NET 提供的一个反射 API(Assembly.LoadFrom)。它允许程序在运行时动态地将外部的 DLL 文件加载到内存中,而不是在编译时就死死绑定。

2. 为什么需要这种架构?(解决什么痛点)

在类似 AutoCAD 这样的宿主程序中,.NET 的 DLL 一旦被加载,就会被进程锁定且无法卸载。这意味着如果你修改了业务代码并重新编译,必须重启 AutoCAD 才能加载新的 DLL,这在调试时极其浪费时间。

采用这种架构后,你可以实现不重启调试

  1. 首次启动主程序,通过 NETLOAD 加载一次稳定的 Loader 壳插件
  2. 在 Loader 中执行一个命令,该命令内部使用 Assembly.LoadFrom("业务DLL路径") 动态加载当前的业务代码。
  3. 在 IDE(如 Visual Studio)中修改业务代码并重新编译(此时因为旧版本已被加载,新版本会直接覆盖磁盘上的旧文件)。
  4. 再次执行 Loader 中的命令,LoadFrom 会加载新生成的业务 DLL,从而实现了代码的热替换和免重启测试。

3. 进阶:文件锁定与卸载问题

虽然 LoadFrom 解决了动态加载的问题,但被加载的 DLL 依然会被操作系统锁定。为了实现彻底的“热替换”和释放文件锁,更高级的做法是引入独立的应用程序域(AppDomain)加载上下文(AssemblyLoadContext)

  • Loader 壳插件会创建一个独立的、可卸载的 AppDomain
  • 在这个独立的沙箱中执行 Assembly.LoadFrom 并运行业务逻辑。
  • 当业务执行完毕或需要更新时,直接卸载这个独立的 AppDomain。这会立即释放对业务 DLL 的文件锁定,让你可以毫无阻碍地重新编译和覆盖它。

总结而言,这套架构是构建插件化系统、模块化开发以及热更新机制的核心基石,它通过“稳定壳子 + 动态反射加载”的方式,完美实现了主程序与业务逻辑的解耦。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐