5.2 KiB
独立功能插件
Modules/ 放置商城业务模块,Plugins/ 放置共用 API 宿主的独立功能。
插件通过 IModule、IStartup 和依赖标记接口接入现有生命周期,控制器共用宿主 URL。
发布和运行
在仓库根目录执行生成命令:
dotnet build Store.API/Store.Api.csproj -c Release
dotnet build Plugins/CloudProduct/Store.CloudProduct.csproj -c Release
dotnet build Plugins/Store.ImageCache/Store.ImageCache.csproj -c Release
dotnet Bin/Store.Api.dll
API 直接生成到仓库根目录 Bin/,不再附加配置名称、目标框架或运行时子目录。
各插件生成后自动将自身完整输出(DLL、deps.json、配置、运行依赖及 runtimes 子目录)复制到
Bin/Plugins/<项目名>/。例如:
Bin/
Store.Api.dll
Store.Api.deps.json
Store.Api.runtimeconfig.json
appsettings.json
Plugins/
Store.CloudProduct/
Store.ImageCache/
生成全部所需项目后即可整体拷贝 Bin/ 部署,目标机器需要兼容的 .NET/ASP.NET Core 运行时。
API 不引用插件,也不会在单独生成 API 时触发插件构建;生成插件项目或生成包含插件的解决方案时会自动复制。
未来在 Plugins 下新增项目会继承同目录的 Directory.Build.props/targets,无需逐个添加复制任务。
Debug 与 Release 共用此目录;部署前应以相同配置重新生成宿主及所需插件。
生成宿主或插件后,都会按相对路径和 SHA-256 清理与宿主完全相同的插件文件;同名但内容不同的文件保留。
宿主尚未生成时插件暂时保留完整依赖,之后生成宿主会自动去重。去重后的插件目录必须与匹配的宿主一起部署。
同一插件输出和部署子目录中的旧入口(其他名称的 .deps.json 及对应 DLL、PDB、runtimeconfig.json)会在生成时自动清理,避免重复加载重命名前的插件。每个部署子目录只放一个插件入口。
其他旧文件不会自动删除;插件部署目录更名、删除或移除依赖后,应清理对应旧目录再生成。
MSBuild 属性 StoreHostOutputPath 可覆盖此路径,覆盖时使用绝对目录并以目录分隔符结尾。
需要标准 publish 产物时也可以指定独立部署目录:
dotnet publish Store.API/Store.Api.csproj -c Release -o artifacts/server
dotnet publish Plugins/CloudProduct/Store.CloudProduct.csproj -c Release -o artifacts/server/Plugins/Store.CloudProduct
dotnet publish Plugins/Store.ImageCache/Store.ImageCache.csproj -c Release -o artifacts/server/Plugins/Store.ImageCache
宿主配置 Plugins:Path 默认为 Plugins,相对路径以宿主二进制目录为基准,也可使用绝对路径。
可以通过环境变量 Plugins__Path 覆盖。目录不存在或为空时不加载插件。
每个插件子目录包含入口 DLL、同名 .deps.json、配置和宿主未提供的依赖;共享依赖由宿主提供。
上面的标准 dotnet publish -o 命令仍生成完整独立发布内容,仅 Bin/Plugins/ 自动执行宿主去重。
加载器递归寻找 .deps.json,由 StoreHubAppTypeFinder.cs 中现有 Match/AvailablePrefix 过滤入口程序集。
依赖解析不受入口名称过滤限制。两个现有插件从自身程序集所在目录读取 JSON 配置。
新增与更新
新增插件无需修改 Store.API:创建类库,引用共享框架,实现需要的模块/启动接口,启用
EnableDynamicLoading,并将配置设置为复制到输出和发布目录;生成后会自动复制到宿主扫描目录;也可以独立发布到其他扫描目录。
配置文件命名与配置节应避免和其他插件冲突。现有模块的配置合并顺序保持不变。
插件、宿主和共享契约必须使用兼容版本。所有程序集加载到默认上下文,同名程序集只加载一次; 发布目录中同名依赖身份不一致会在加载时明确报错,不提供依赖版本隔离。 插件必需的程序集、类型或配置缺失时启动失败;未调用的第三方可选功能依赖可能在调用时才解析。
插件与宿主同进程运行,共用认证、容器和中间件。更新时替换完整发布目录并重启宿主; 不支持热加载、卸载和进程隔离。CloudProduct 仍需要其数据库、OpenSearch 和后台任务配置。
加载冒烟验证
验证程序不连接数据库或 OpenSearch;每个场景单独启动进程:
dotnet run --project Tests/PluginLoadingSmoke -- <插件根目录>
dotnet run --project Tests/PluginLoadingSmoke -- <仅包含ImageCache的发布目录> image
dotnet run --project Tests/PluginLoadingSmoke -- <空目录或不存在目录> empty
dotnet run --project Tests/PluginLoadingSmoke -- - empty
dotnet run --project Tests/PluginLoadingSmoke -- <缺依赖或包含版本冲突的目录> failure
- 使用默认 Plugins 路径;默认路径下已部署插件时使用普通模式。
普通模式验证两个插件及控制器发现和程序集去重;image 额外验证真实框架注册流程中的配置、DI、IStartup 和 MVC。
将同一插件发布内容复制到另一子目录可验证重复程序集;缺失依赖和版本冲突应报告具体插件路径。