.NET: 如何通过AppDomain动态加载插件程序

本文介绍了一种基于C#的插件系统实现方法,包括定义插件接口、创建插件类、通过AppDomain隔离加载插件,并使用TypeLoader动态加载未标记为可序列化的插件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是今天课堂上的一个小例子程序

1. 接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Interfaces
{
    public interface IPlugin
    {
        void Run();
    }
}

2. 插件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PluginLib
{
    [Serializable]
    public class Plugin:Interfaces.IPlugin
    {
        public void Run() {
            Console.WriteLine("插件在运行");
        }


    }
}

3. 主程序

            AppDomain plugindomain = AppDomain.CreateDomain("PluginDomain");

            #region 使用接口的方式来动态执行方法
            Interfaces.IPlugin plugin = (Interfaces.IPlugin)plugindomain.CreateInstanceFromAndUnwrap("PluginLib.dll", "PluginLib.Plugin");

            plugin.Run();


            Console.WriteLine("在插件程序域中加载的程序集");
            foreach (var item in plugindomain.GetAssemblies())
            {
                Console.WriteLine(item.FullName);
            }
            #endregion

结果如下

image

注意:这种方式加载的插件,里面的类型必须声明可序列化([Serializable] ),否则就会出现下面的错误

image

 

 

但是,如果插件真的没有声明可序列化,是不是就没有办法呢?也不是这么说

4. 在主程序中添加一个TypeLoader

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Reflection;
using System.IO;

namespace _08_AppDomain_ServiceSample
{
    [Serializable]
    public class TypeLoader
    {
        public Assembly LoadAssembly(string path) {
            return Assembly.LoadFile(Path.Combine(Environment.CurrentDirectory, path));
        }
    }
}

 

5. 修改代码,利用TypeLoader作为中间人,去动态加载那些插件程序集


            #region 使用加载代理的方式
            TypeLoader loader = (TypeLoader)plugindomain.CreateInstanceFromAndUnwrap("08_AppDomain_ServiceSample.exe", typeof(TypeLoader).FullName);
            Interfaces.IPlugin plugin = (Interfaces.IPlugin)loader.LoadAssembly("PluginLib.dll").CreateInstance("PluginLib.Plugin");
            plugin.Run();
            Console.WriteLine("在插件程序域中加载的程序集");
            foreach (var item in plugindomain.GetAssemblies())
            {
                Console.WriteLine(item.FullName);
            }

            AppDomain.Unload(plugindomain);

            #endregion

image

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值