博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模块式开发
阅读量:4614 次
发布时间:2019-06-09

本文共 6160 字,大约阅读时间需要 20 分钟。

这两天看到同事的一个小工具,用的是模块式开发,也就是俗称的插件开发,用的是反射+接口的方式实现的。感觉挺好的,也就学习了一下,写个小Demo,在此记录下。

一、写接口类

接口类是所有模块的基础,因为让主程序去寻找模块,就是通过反射来找到继承此接口的相关项目,也就是后期包含继承此接口类的DLL文件。

此接口类包含以下几个属性

工具的名称(必需)、是否要弹出、前景色、背景色、工具启动方法(必需)

public interface IToolsInterface    {        ///         /// 获取工具名称        ///         string ToolName        {            get;        }        ///         /// 是否弹出        ///         bool IsPopUp        {            get;        }        ///         /// 前景色        ///         Brush ForgroundBrush        {            get;        }        ///         /// 背景色        ///         Brush BackgroundBrush        {            get;        }        ///         /// 工具启动方法        ///         /// 
FrameworkElement RunToolApplication(); }

二、写主窗体

所谓的主窗体,也就是各个模块的承载器而已,因为各个模块都是UserControl,需要窗体来承载。

需要的方法大概有两个,寻找目录的层级、创建相应的模块。

1、寻找目录层级

因为模块最终要生成到一个位置,然后让主程序去搜索,所以,需要一个搜索方法,去寻找

///         /// 查找指定目录下的所有末级子目录        ///         /// 要查找的目录        /// 查找结果列表        /// 是否包含系统目录        /// 是否包含隐藏目录        public static void GetEndDirectories(DirectoryInfo dir,List
dirList,bool system=false,bool hidden=false) { try { //返回当前目录的子目录集合 DirectoryInfo[] dirSub = dir.GetDirectories(); if(dirSub.Length==0) { //如果没有子目录了则添加进列表 dirList.Add(dir); return; } foreach (DirectoryInfo subItem in dirSub) { //跳过系统目录 if (!system && (subItem.Attributes & FileAttributes.System)==FileAttributes.System) { continue; } //跳过隐藏目录 if (!hidden && (subItem.Attributes & FileAttributes.Hidden)==FileAttributes.Hidden) { continue; } //递归 GetEndDirectories(subItem, dirList); } } catch (Exception ex) { MessageBox.Show("获取目录层级失败。" + ex.Message); } }

2、创建相应模块

当存在一个DLL时,就生成一个模块,两个DLL时就要有两个模块,以此类推……

    ///         /// 创建功能按钮        ///         ///         /// 
private UIElement CreateFunction(IToolsInterface toolsInterface) { Button btn = new Button(); btn.Click += Btn_Click; btn.Content = toolsInterface.ToolName; btn.Width = 100; btn.Height = 50; btn.Margin = new Thickness(5, 0, 0, 0); btn.Background = toolsInterface.BackgroundBrush; btn.Foreground = toolsInterface.ForgroundBrush; btn.Tag = toolsInterface; return btn; } private void Btn_Click(object sender, RoutedEventArgs e) { Button btn = sender as Button; if(btn!=null) { IToolsInterface toolsInterface = btn.Tag as IToolsInterface; if(toolsInterface !=null) { FrameworkElement control = toolsInterface.RunToolApplication(); gUc.Children.Clear(); gUc.Children.Add(control); } else { MessageBox.Show("实例化接口失败"); } } else { MessageBox.Show("实例化按钮失败"); } }

3、加载模块

     private void LoadWidgets()        {            string applicationPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;            string dirPath = applicationPath + "Widgets/";            if(!Directory.Exists(dirPath))            {                MessageBox.Show("未找到相关的Widgets文件夹信息,请确认相关的文件夹是否存在。");                return;            }            DirectoryInfo dir = new DirectoryInfo(dirPath);            List
lastDirNameList = new List
(); Tools.FileToolsHelper.GetEndDirectories(dir, lastDirNameList); foreach (DirectoryInfo item in lastDirNameList) { WrapPanel wrapPanel = null; TabItem tabItem = Tools.UCToolsHelper.CreateTabByDirName(item.Name,tcToolkClass); wrapPanel = Tools.UCToolsHelper.CreateWrapPanel(tabItem); string[] dllFilesPath = Directory.GetFiles(item.FullName, "*.dll"); foreach (string dllPath in dllFilesPath) { Assembly assembly = Assembly.LoadFile(dllPath); Type[] types = assembly.GetExportedTypes(); foreach (Type type in types) { if(typeof(IToolsInterface).IsAssignableFrom(type)&&!type.IsAbstract) { IToolsInterface toolInterface = Activator.CreateInstance(type) as IToolsInterface; if (toolInterface !=null) { wrapPanel.Children.Add(CreateFunction(toolInterface)); } } } } } }

三、写相应的模块部分

最近也没写什么小东西,就把原来做的两个Winform东西,直接搬过来,弄成了WPF的,把窗体改成了UserControl,额外加了一个类,用来实现第一部分提到的接口。

其中一个小工具在这:

基本东西不动,只是加了一个FunctionHelper用来实现接口,此处需要注意,一定是Public,否则查询不到

public class FunctionHelper : IToolsInterface    {        public Brush BackgroundBrush        {            get            {                return new SolidColorBrush(Colors.LightBlue);            }        }        public Brush ForgroundBrush        {            get            {                return new SolidColorBrush(Colors.YellowGreen);            }        }        public bool IsPopUp        {            get            {                return false;            }        }        public string ToolName        {            get            {                return "方法查询工具";            }        }        public FrameworkElement RunToolApplication()        {            return new SearchUC();        }    }

四、看一下效果图

大概也就这么一个流程,不是很难,方便了后期的开发。

DEMO还有很多不完善的地方,我会慢慢弄,后期会不断的完善

转载于:https://www.cnblogs.com/ZXdeveloper/p/5959476.html

你可能感兴趣的文章
LeetCode-Find the Celebrity
查看>>
LeetCode-Longest Increasing Subsequence
查看>>
LeetCode-Reverse Bits
查看>>
zynq如何查看当前网速
查看>>
vue+element-ui实现表格checkbox单选
查看>>
linux公司常用基础命令必知必会
查看>>
网站优化
查看>>
Java高级特性 第5节 序列化和、反射机制
查看>>
每天敲一点code
查看>>
jquery
查看>>
IntelliJ IDEA 中文乱码问题解决办法
查看>>
【文文殿下】网络流24题计划
查看>>
Coursera台大机器学习课程笔记6 -- The VC Dimension
查看>>
Ubuntu 16 04 安装KVM
查看>>
【openlayers】CSS3样式的Popups
查看>>
常用表单及控件测试用例检查点总结
查看>>
UVA5874 Social Holidaying 二分匹配
查看>>
网络流24题 餐巾计划(费用流)
查看>>
Codeforces Round #478 (Div. 2) D Ghosts 会超时的判断两个之间关系,可以用map
查看>>
box-shadow
查看>>