这篇博客主要要讲的是反射在C#编程中的一些使用:
主要目的是为了让程序能动态识别插件并加载到主程序当中。 这个功能是一个实用的功能。
首先,我们需要定义一个接口
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。
么么么么哒
时间: 2024-09-29 09:10:45