C#博客随笔之七:反射初体验

这篇博客主要要讲的是反射在C#编程中的一些使用:

主要目的是为了让程序能动态识别插件并加载到主程序当中。 这个功能是灰常实用的哦。

ok!

首先,我们需要定义一个接口

public interface IPlug
    {

        /// <summary>
        /// 获得版本号
        /// </summary>
        /// <returns>返回版本</returns>
        string GetVersion();
        /// <summary>
        /// 获得插件作者
        /// </summary>
        /// <returns></returns>
        string GetAuthor();
        /// <summary>
        /// 获得插件名
        /// </summary>
        /// <returns></returns>
        string GetName();
        /// <summary>
        /// 获得程序图标
        /// </summary>
        /// <returns></returns>
        System.Windows.Media.Imaging.BitmapImage GetImage();
        /// <summary>
        /// 在主程序加载的时候执行,用来产生用户提醒
        /// </summary>
        void Initial();

        string GetDescribe();
        UserControl GetPage();
    }

这个接口定义了插件需要实现的函数,这些方法是需要插件自己具体实现的,具体的方法描述,都在注释里面了呢。

GetPage方法是调用插件的页面并返回。 

我们在编写插件的时候,就应该在插件的页面这么写:

public partial class Viewscore : UserControl,IPlug

后边要继承接口Iplug并予以实现

差不多就是这样

public string GetVersion()
        {
            return "1.0.0";
        }

        public string GetAuthor()
        {
            return "TJUBOX";
        }

        public string GetName()
        {
            return "插件测试";
        }

        public BitmapImage GetImage()
        {
            CommonFuncClass cfc = new CommonFuncClass();
       //这是从资源文件中加载图片 return cfc.BitmapToBitmapImage(global::Plugin_EWebScore.Properties.Resources.logo); } public void Initial() { } public string GetDescribe() { return "这是一个插件测试"; } public UserControl GetPage() { return this; }

接下来最关键的部分到了,就是怎么样在主程序中发现插件的存在

 public class PluginManager
    {
        public PluginManager()
        {
            GetPlugList();
            GetPlugInfo();
        }
        public ArrayList plugins = new ArrayList();
        //获取插件目录
        string[] files = Directory.GetFiles(Configuration.PluginRoot);
        List<string> dllfile = new List<string>();
        object selObj;
        public void GetPlugList()
        {
            //遍历目录中的文件
            foreach (string file in files)
            {
                //如果文件名以dll结尾
                if (file.ToUpper().EndsWith(".DLL"))
                {
                    Assembly ab = Assembly.LoadFile(file);
                    Type[] types = ab.GetTypes();
                    foreach (Type t in types)
                    {
                        //如果他实现了IPlug接口
                        if (t.GetInterface("IPlug") != null)
                        {
                            //那么将他加入到插件列表
                            plugins.Add(ab.CreateInstance(t.FullName));
                        }
                    }
                }
            }
        }
        public ObservableCollection<PlugInfo> plugList = new ObservableCollection<PlugInfo>();
        public void GetPlugInfo()
        {
            for (int i = 0; i < plugins.Count; i++)
            {
                try
                {
                    //获取插件信息
                    MethodInfo name;
                    MethodInfo version;
                    MethodInfo author;
                    MethodInfo logo;
                    MethodInfo page;
                    MethodInfo desc;
                    selObj = plugins[i];
                    Type t = selObj.GetType();
                    name = t.GetMethod("GetName");
                    version = t.GetMethod("GetVersion");
                    author = t.GetMethod("GetAuthor");
                    logo = t.GetMethod("GetImage");
                    page = t.GetMethod("GetPage");
                    desc = t.GetMethod("GetDescribe");
                    PlugInfo pi = new PlugInfo();
                    pi.Author = author.Invoke(selObj, null).ToString();
                    pi.PlugName = name.Invoke(selObj, null).ToString();
                    pi.Version = version.Invoke(selObj, null).ToString();
                    pi.PlugName = name.Invoke(selObj, null).ToString();
                    pi.Logo = logo.Invoke(selObj, null) as System.Windows.Media.Imaging.BitmapImage ;
                    pi.Page = page.Invoke(selObj, null) as UserControl;
                    pi.Describe = desc.Invoke(selObj, null).ToString();
                    plugList.Add(pi);
                }
                catch { }
            }
        }
    }

 写一个manager 用来发现插件并添加都插件列表

其实这部分内容很简单,我们加载文件,通过反射来获取文件的相关信息:

  Assembly ab = Assembly.LoadFile(file);
                    Type[] types = ab.GetTypes();

我们可以看到这个

public ObservableCollection<PlugInfo> plugList = new ObservableCollection<PlugInfo>();

 这个其实使用了mvvm里面的输入绑定的另外一部分,这样,数据源的任何变动都会被推送到view层进行同步。这就与上一篇的数据绑定联系上了。

活学活用,have fun。

么么么么哒

原文地址:https://www.cnblogs.com/MelodyWang/p/4475819.html