标签:
插件编程技术
插件是指遵循一定的接口规范、可以动态加载和运行的程序模块。利用反射的动态加载代码能力,可以很容易的实现插件,
插件编程的要点是使用接口来定义插件的功能特征。插件的宿主程序通过接口来确认、装载和执行插件的功能,实现插件功能的所有类都必须实现定义插件的接口。
1、首先定义一个关机的接口 IShut,生成程序集,并在UI层(Winform窗体)来添加引用
  public interface IShut
    {
        string Name { get; }
        void ShutDownCPU(int time);
    }
2、再通过一个类ShutDownClass 来实现接口IShut,并生成程序集,
	以后就通过实现接口IShut来实现更多的功能:
class ShutDownClass : IShut
    {
        public string Name
        {
            get { return "关机插件"; }
        }
        public void ShutDownCPU(int time)
        {
            ShutDown(time);
        }
        public void ShutDown(int second)
        {
          //以下来设置关机的一些属性
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardInput = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.CreateNoWindow = true;
            process.Start();
            process.StandardInput.WriteLine("shutdown -s -f -t " + second);
            //process.StandardInput.WriteLine("dir c:");
            process.StandardInput.WriteLine("exit");
            process.Close();
            process.Dispose();
        }
    }    
3、UI是通过Winform来实现的,也就通过一个控件ToolStripMenuItem
	
	UI层是通过反射来获得ShutDownClass.dll的程序集 中的类,成员,属性
	
	通过 GetTypes()方法可以获得程序集中的所有成员
         Assembly ass = Assembly.LoadFile(item);
                //获得程序集中的成员
                Type[] types = ass.GetTypes();
通过 Activator.CreateInstance()可以获得Type类中的对象,返回的object类型
	需传入Type类型
	用法:
//创建对象
IShut shut = Activator.CreateInstance(types[i]) as IShut;
Type类:
		---->IsAssignableFrom()函数,判断某一个类是否可以赋值给另一个类。是否符合里氏代换的原则!
		---->IsInstanceOfType()函数,判断是否是指定类的实例。
		---->IsSubclassOf()函数,判断是否是某个类的子类,注意!!!没有接口的事儿!!!!
		---->IsAbstract()函数,判断某一个类是否是抽象的。
		
		用法:
 if (typeof(IShut).IsAssignableFrom(types[i]) && !types[i].IsAbstract)
UI层的代码
 private void Form1_Load(object sender, EventArgs e)
        {
            //功能ToolStripMenuItem.DropDown.Items.Add("关机");
            //功能ToolStripMenuItem.DropDown.Items.Add("重启");
            //获得plug文件夹的全路径
            string path = Path.GetFullPath("plug");
            //获得plug文件夹中所有的文件
            string[] files = Directory.GetFiles(path, "*.dll");
            //遍历files
            foreach (string item in files)
            {
                //item:dll文件的绝对路径
                Assembly ass = Assembly.LoadFile(item);
                //获得程序集中的成员
                Type[] types = ass.GetTypes();
                //判断是否是我们需要的成员
                for (int i = 0; i < types.Length; i++)
                {
                    if (typeof(IShut).IsAssignableFrom(types[i]) && !types[i].IsAbstract)
                    {
                        //当前的数据使我们需要的数据
                        //创建对象
                        IShut shut = Activator.CreateInstance(types[i]) as IShut;
                        //创建菜单
                        ToolStripItem tsi = 功能ToolStripMenuItem.DropDown.Items.Add(shut.Name);
                        //存储shut
                        tsi.Tag = shut;
                        //注册单击事件
                        tsi.Click += tsi_Click;
                    }
                }
            }
        }
        void tsi_Click(object sender, EventArgs e)
        {
            ToolStripItem tsi = sender as ToolStripItem;
            IShut s = tsi.Tag as IShut;
            s.ShutDownCPU(1200);
        }
扩展:
 如果需动态调用类中的成员:(也是Type类中的方法 )
		MemberInfo:抽象父类
		PropertyInfo:获取属性
		MethodInfo:获取方法
		FieldInfo:获取字段
		EventInfo:获取事件
用法:
//获得单个的数据成员
Assembly ass = Assembly.LoadFile(Path.GetFullPath("Common.dll"));
//获得程序集中Person类型信息
Type t = ass.GetType("Common.Person");    
//创建Person类对象o
//object o = ass.CreateInstance("Common.Person");
//获得类中的单个成员方法
MethodInfo m = t.GetMethod("SayHello");
////调用方法
m.Invoke(o, null);
标签:
原文地址:http://www.cnblogs.com/Raymond201508/p/4769610.html