zoukankan      html  css  js  c++  java
  • .NET: 如何通过AppDomain动态加载插件程序

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

    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

  • 相关阅读:
    [Canvas]英雄可以射箭了
    [Canvas]人物型英雄出现(前作仅为箭头)
    day33_Spring学习回顾_01
    day33_Spring学习笔记_01
    MyEclipse中,当我们写一个类实现一个接口时,会自动生成重写该接口的方法,但是,方法的参数提示不够好,是什么原因导致的呢?该如何解决呢?
    使用Junit测试一个 spring静态工厂实例化bean 的例子,所有代码都没有问题,但是出现java.lang.IllegalArgumentException异常
    MyEclipse中如何变换查看项目文件夹
    实战网卡bond
    Centos7上使用官方YUM源安装Mysql
    CentOS 7上安装WordPress详细步骤
  • 原文地址:https://www.cnblogs.com/chenxizhang/p/1625953.html
Copyright © 2011-2022 走看看