码迷,mamicode.com
首页 > Windows程序 > 详细

利用C#中的反射机制来实现关机插件

时间:2015-08-29 20:11:39      阅读:235      评论:0      收藏:0      [点我收藏+]

标签:

插件编程技术

插件是指遵循一定的接口规范、可以动态加载和运行的程序模块。利用反射的动态加载代码能力,可以很容易的实现插件,

插件编程的要点是使用接口来定义插件的功能特征。插件的宿主程序通过接口来确认、装载和执行插件的功能,实现插件功能的所有类都必须实现定义插件的接口。

 

 

 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);

 

 

利用C#中的反射机制来实现关机插件

标签:

原文地址:http://www.cnblogs.com/Raymond201508/p/4769610.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!