0

0

c# 如何实现插件化开发

煙雲

煙雲

发布时间:2026-01-14 00:49:27

|

432人浏览过

|

来源于php中文网

原创

C#插件化开发核心是运行时动态加载程序集并调用约定接口类型,依赖AssemblyLoadContext(.NET Core 3.0+)实现隔离与卸载,需共享接口契约、独立加载上下文及严格版本匹配。

c# 如何实现插件化开发

什么是 C# 插件化开发的核心机制

插件化开发在 C# 中本质是运行时动态加载程序集(.dll),并调用其中实现约定接口的类型。它不依赖编译期引用,而是靠反射 + 接口契约 + AssemblyLoadContext(.NET Core 3.0+)或 AppDomain(.NET Framework)来隔离和管理生命周期。

关键判断:如果你只是想“换配置就换行为”,不用插件;但需要第三方独立发布功能模块、热更新业务逻辑、或隔离崩溃风险,那才真正需要插件化。

AssemblyLoadContext 实现可卸载插件(推荐 .NET 5+)

AppDomain 已在 .NET Core 中移除,AssemblyLoadContext 是唯一支持卸载的机制。不使用它会导致插件 DLL 锁死、内存泄漏、类型冲突。

  • 必须为每个插件创建独立的派生类(如 PluginLoadContext : AssemblyLoadContext),重写 Load 方法以控制依赖解析
  • 插件程序集及其所有依赖(非框架类库)必须显式加载进该上下文,否则会 fallback 到默认上下文,导致无法卸载
  • 插件类型不能直接返回 stringList 等托管对象给宿主——跨上下文传递需用接口(定义在共享程序集)、序列化或原始数据(byte[]
  • 调用插件前,必须用 context.LoadFromAssemblyPath(path) 加载,再通过 assembly.CreateInstance(typeName) 实例化
public class PluginLoadContext : AssemblyLoadContext
{
    private readonly AssemblyDependencyResolver _resolver;
    public PluginLoadContext(string pluginPath) : base(isCollectible: true)
    {
        _resolver = new AssemblyDependencyResolver(pluginPath);
    }
    protected override Assembly Load(AssemblyName assemblyName)
    {
        string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
        return assemblyPath != null ? LoadFromAssemblyPath(assemblyPath) : null;
    }
}

插件与宿主如何约定通信接口

接口必须定义在**宿主与插件共同引用的独立程序集**(如 PluginContract.dll)中,且该程序集不能包含任何插件私有依赖。否则会出现 System.TypeLoadException: Could not load type ... from assembly

mallcloud商城
mallcloud商城

mallcloud商城基于SpringBoot2.x、SpringCloud和SpringCloudAlibaba并采用前后端分离vue的企业级微服务敏捷开发系统架构。并引入组件化的思想实现高内聚低耦合,项目代码简洁注释丰富上手容易,适合学习和企业中使用。真正实现了基于RBAC、jwt和oauth2的无状态统一权限认证的解决方案,面向互联网设计同时适合B端和C端用户,支持CI/CD多环境部署,并提

下载
  • 接口方法参数/返回值只能是基础类型(intstringDateTime)、共享接口、或 Stream/MemoryStream
  • 避免在接口中暴露 TaskIEnumerable —— 宿主和插件可能使用不同版本的 System.Runtime,引发泛型类型不匹配
  • 建议增加 Initialize(IConfiguration config) 方法,让插件自行读取配置,而不是由宿主传入 IConfiguration(该类型跨上下文不可用)
  • 插件实现类必须有无参构造函数,否则 CreateInstance 失败

常见失败场景和绕过方式

插件加载失败往往不是代码问题,而是环境或路径细节没对齐:

  • FileNotFoundException:插件 DLL 缺少本地依赖(如 sqlite3.dlllibSkiaSharp.so)。解决:把原生库复制到插件目录,并在 PluginLoadContext.Load 中监听 ResolvingUnmanagedDll 事件手动加载
  • InvalidCastException:看似实现了接口,实则引用了不同版本的 PluginContract.dll。解决:强制所有项目引用同一 NuGet 包或项目引用,检查输出目录是否混入旧版 PluginContract.dll
  • 插件能加载但方法调用后整个进程卡死:插件内启动了同步阻塞 I/O(如 File.ReadAllText 在大文件上)或未处理的异常未被 catch。解决:宿主调用统一包装在 try/catch + CancellationToken 中,并限制执行超时
  • .NET Framework 下无法卸载:只能用 AppDomain.CreateDomain 隔离,但卸载后该域内所有线程必须退出,且静态字段不会重置。实际生产中已不推荐

最易被忽略的一点:插件程序集的 TargetFramework 必须与宿主完全一致(如都是 net6.0),哪怕只差一个补丁号(net6.0.1 vs net6.0.2)都可能导致 AssemblyLoadContext 拒绝加载。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

537

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

52

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

194

2025.08.29

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1016

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

62

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

389

2025.12.29

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

3

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 45.5万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号