乐于分享
好东西不私藏

.NET 插件式架构实战,基于 AssemblyLoadContext 实现

.NET 插件式架构实战,基于 AssemblyLoadContext 实现

一、架构概述

插件式架构是一种将系统功能模块化、支持动态扩展的软件设计模式。在 .NET Core 3.0 及之后的版本中,AssemblyLoadContext(简称 ALC)提供了程序集加载隔离能力,支持插件的独立加载、依赖隔离与热卸载,是实现现代化插件系统的核心基础设施。

1.1 核心优势

  • 隔离加载:每个插件运行在独立的 ALC 中,避免版本冲突

  • 可卸载性:支持插件热卸载,释放内存与资源

  • 依赖隔离:插件可自带专属版本依赖,不与主程序冲突

  • 动态扩展:运行时发现、加载、启用/禁用插件,无需重启主程序

1.2 典型应用场景

  • 上位机软件的功能模块动态加载

  • 业务系统的第三方扩展机制

  • 规则引擎、脚本引擎的隔离执行

  • 模块化 SaaS 平台的租户功能定制

二、AssemblyLoadContext 核心原理

2.1 基本概念

AssemblyLoadContext 是 .NET 运行时中负责程序集加载的抽象上下文。默认情况下,整个应用程序共享一个默认上下文(Default)。通过创建自定义 ALC,可以将插件程序集加载到独立上下文中,实现隔离。

2.2 关键特性

  1. 加载解析:每个 ALC 有独立的程序集解析逻辑

  2. 依赖共享:可设置将主程序程序集共享给插件使用

  3. 可卸载Collectible 属性为 true 的 ALC 支持整体卸载

  4. 类型同一性:不同 ALC 中加载的同类型,运行时视为不同类型

2.3 卸载条件

  • ALC 必须标记为可收集(isCollectible: true

  • 释放所有对插件对象的引用

  • 释放 ALC 本身的引用

  • 触发 GC 回收

三、项目整体架构设计

3.1 分层结构

3.2 设计原则

  • 契约分离:接口与实现分离,主程序只依赖契约

  • 单向依赖:插件依赖主程序契约,主程序不直接依赖插件

  • 依赖注入友好:支持将插件服务注册到主程序 DI 容器

  • 统一生命周期:插件加载、初始化、执行、卸载全流程管控

四、完整源码实现

4.1 插件契约层(PluginHost.Contracts)

IPlugin.cs

IPluginFactory.cs

4.2 插件加载核心层(PluginHost.Core)

PluginLoadContext.cs

PluginLoader.cs

PluginManager.cs

4.3 示例插件实现

HelloPlugin 项目

HelloPluginFactory.cs

HelloPlugin.cs

CalcPlugin 项目

4.4 主程序宿主(PluginHost.App)

Program.cs

五、项目构建与部署配置

5.1 插件项目关键配置

每个插件的 .csproj 文件需设置:

关键说明:

  • CopyLocalLockFileAssemblies=true:将 NuGet 依赖复制到输出目录

  • <Private>false + <ExcludeAssets>runtime</ExcludeAssets>:契约程序集不随插件输出,由主程序共享

5.2 目录结构部署

六、高级特性扩展

6.1 插件发现机制

6.2 插件配置文件(plugin.json)

6.3 卸载验证

七、常见坑与最佳实践

7.1 典型陷阱

  1. 类型不匹配:不同 ALC 加载的同名称类型不可互转,必须通过共享契约接口交互

  2. 泄漏引用:事件订阅、静态变量、回调等会导致 ALC 无法卸载

  3. 依赖冲突:共享程序集版本不一致会引发加载异常

  4. 文件锁定LoadFromAssemblyPath 会锁定文件,建议先加载到内存流

7.2 最佳实践

  • 契约最小化:共享契约程序集尽量精简,减少依赖

  • 工厂模式:通过工厂创建插件实例,避免直接反射创建

  • 统一异常处理:插件执行必须包裹 try-catch,防止插件崩溃拖垮主程序

  • 版本兼容:契约接口变更需考虑向后兼容

  • 资源释放:插件实现 IDisposable 或 IAsyncDisposable,卸载前确保资源释放

7.3 性能优化

  • 插件加载按需进行,避免启动时全部加载

  • 频繁加载卸载的场景考虑插件池化

  • 大型插件可考虑延迟加载依赖程序集

八、总结

基于 AssemblyLoadContext 的插件式架构为 .NET 应用提供了强大的动态扩展能力。通过合理的契约设计、加载隔离和生命周期管控,可以构建出高可扩展性、高稳定性的插件化系统。该架构在工业上位机、业务平台、工具软件等领域有极高的实用价值。

完整项目可直接基于上述代码搭建,目标框架建议使用 .NET 8 或 .NET 9,以获得最佳的 ALC 功能与性能表现。


【源码】
关注评论或者回复【777】得:《.NET 插件式架构实战,基于 AssemblyLoadContext 实现的详细实战资料和完整源码》