当前位置: 代码网 > it编程>编程语言>Asp.net > C#动态加载程序集的全攻略

C#动态加载程序集的全攻略

2025年09月07日 Asp.net 我要评论
引言在 c# 中,动态加载程序集(dynamic assembly loading)是一种常见的需求,特别是在需要模块化、插件化或运行时扩展功能的场景中。以下是如何实现 c# 代码依赖的动态加载的详细

引言

在 c# 中,动态加载程序集(dynamic assembly loading)是一种常见的需求,特别是在需要模块化、插件化或运行时扩展功能的场景中。以下是如何实现 c# 代码依赖的动态加载的详细说明,结合了知识库中的关键信息和实际应用技巧。

一、动态加载程序集的核心方法

c# 提供了多种方式动态加载程序集,以下是三种常用方法及其区别:

1. assembly.load

  • 特点
    • 通过程序集名称加载(不带路径)。
    • 会自动加载依赖项(如果依赖项在 gac 或当前目录中)。
    • 适合已知程序集名称且依赖项已存在的场景。
  • 示例
assembly assembly = assembly.load("myassembly");

2. assembly.loadfrom

  • 特点
    • 通过文件路径加载程序集(支持相对或绝对路径)。
    • 会自动加载依赖项(如果依赖项在 gac 或当前目录中)。
    • 即使路径不同,相同名称的程序集 会被视为同一实例。
  • 示例
assembly assembly = assembly.loadfrom("c:\\myassembly.dll");

3. assembly.loadfile

  • 特点
    • 通过文件路径加载程序集,不自动加载依赖项
    • 可以加载多个同名但不同路径的程序集(视为不同实例)。
    • 需要手动处理依赖项加载(通过 appdomain.assemblyresolve 事件)。
  • 示例
assembly assembly = assembly.loadfile("c:\\myassembly.dll");

二、动态加载程序集的完整流程

以下是一个完整的动态加载程序集并调用其功能的示例:

1. 加载程序集

string path = @"c:\myassembly.dll";
assembly assembly = assembly.loadfile(path);

2. 获取类型并创建实例

// 获取类型(需指定命名空间和类名)
type type = assembly.gettype("mynamespace.myclass");

// 创建实例(无参构造函数)
object instance = activator.createinstance(type);

3. 调用方法

// 获取方法信息
methodinfo method = type.getmethod("mymethod");

// 调用方法(无参)
method.invoke(instance, null);

4. 处理依赖项(如果使用 loadfile)

如果程序集依赖其他 dll,需通过 appdomain.assemblyresolve 事件手动加载依赖项:

appdomain.currentdomain.assemblyresolve += (sender, args) =>
{
    string dependencypath = @"c:\mydependency.dll";
    return file.exists(dependencypath) ? assembly.loadfile(dependencypath) : null;
};

三、动态加载的典型应用场景

1. 插件系统

通过动态加载外部 dll 实现模块化扩展:

// 加载插件
assembly pluginassembly = assembly.loadfrom("plugin.dll");

// 查找所有实现 iplugin 接口的类型
foreach (type type in pluginassembly.gettypes())
{
    if (typeof(iplugin).isassignablefrom(type) && !type.isinterface)
    {
        iplugin plugin = (iplugin)activator.createinstance(type);
        plugin.execute();
    }
}

2. 模块化应用

根据用户配置动态加载功能模块:

string modulename = "modulea";
assembly moduleassembly = assembly.load(modulename);
type moduletype = moduleassembly.gettype($"{modulename}.moduleclass");
object moduleinstance = activator.createinstance(moduletype);

3. 动态资源加载

动态加载资源文件(如语言包):

assembly resourceassembly = assembly.load("resources");
resourcemanager rm = new resourcemanager("myresources", resourceassembly);
string localizedtext = rm.getstring("welcomemessage");

四、注意事项与最佳实践

1. 依赖项管理

  • loadfrom:适合大多数场景,依赖项会自动加载(需确保依赖项在路径中)。
  • loadfile:需手动处理依赖项,适合需要隔离加载或加载多个同名程序集的场景。

2. 安全性

  • 确保动态加载的程序集来源可信,避免加载恶意代码。
  • 使用 appdomain 隔离加载程序集,限制其权限(如沙箱环境)。

3. 性能优化

  • 缓存 methodinfoconstructorinfo 等反射对象,避免频繁反射调用。
  • 对于高频调用的方法,考虑使用 system.linq.expressions 生成委托代替 invoke

4. 卸载程序集

c# 中无法直接卸载单个程序集,需通过卸载整个 appdomain 实现:

// 创建新 appdomain 并加载程序集
appdomain domain = appdomain.createdomain("plugindomain");
domain.load("myassembly");

// 卸载 appdomain 以释放程序集
appdomain.unload(domain);

五、完整示例:动态加载并调用 dll

using system;
using system.io;
using system.reflection;

class program
{
    static void main()
    {
        // 注册依赖项加载事件
        appdomain.currentdomain.assemblyresolve += currentdomain_assemblyresolve;

        // 动态加载主程序集
        string maindllpath = @"c:\mainassembly.dll";
        assembly mainassembly = assembly.loadfile(maindllpath);

        // 获取类型并创建实例
        type maintype = mainassembly.gettype("mainnamespace.mainclass");
        object maininstance = activator.createinstance(maintype);

        // 调用方法
        methodinfo method = maintype.getmethod("run");
        method.invoke(maininstance, null);
    }

    private static assembly currentdomain_assemblyresolve(object sender, resolveeventargs args)
    {
        // 手动加载依赖项
        string dependencypath = path.combine(@"c:\dependencies", new assemblyname(args.name).name + ".dll");
        return file.exists(dependencypath) ? assembly.loadfile(dependencypath) : null;
    }
}

六、总结

动态加载程序集是 c# 实现灵活架构的关键技术,适用于插件系统、模块化设计和运行时扩展等场景。通过合理选择 assembly.loadloadfromloadfile,结合依赖项管理和性能优化,可以高效实现动态加载需求。同时,需注意安全性和资源隔离,确保应用程序的稳定性和可控性。

以上就是c#动态加载程序集的全攻略的详细内容,更多关于c#动态加载程序集的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com