模塊式開發

来源:http://www.cnblogs.com/ZXdeveloper/archive/2016/10/14/5959476.html
-Advertisement-
Play Games

這兩天看到同事的一個小工具,用的是模塊式開發,也就是俗稱的插件開發,用的是反射+介面的方式實現的。感覺挺好的,也就學習了一下,寫個小Demo,在此記錄下。 一、寫介面類 介面類是所有模塊的基礎,因為讓主程式去尋找模塊,就是通過反射來找到繼承此介面的相關項目,也就是後期包含繼承此介面類的DLL文件。 ...


這兩天看到同事的一個小工具,用的是模塊式開發,也就是俗稱的插件開發,用的是反射+介面的方式實現的。感覺挺好的,也就學習了一下,寫個小Demo,在此記錄下。

一、寫介面類

介面類是所有模塊的基礎,因為讓主程式去尋找模塊,就是通過反射來找到繼承此介面的相關項目,也就是後期包含繼承此介面類的DLL文件。

此介面類包含以下幾個屬性

工具的名稱(必需)、是否要彈出、前景色、背景色、工具啟動方法(必需)

public interface IToolsInterface
    {
        /// <summary>
        /// 獲取工具名稱
        /// </summary>
        string ToolName
        {
            get;
        }
        /// <summary>
        /// 是否彈出
        /// </summary>
        bool IsPopUp
        {
            get;
        }
        /// <summary>
        /// 前景色
        /// </summary>
        Brush ForgroundBrush
        {
            get;
        }
        /// <summary>
        /// 背景色
        /// </summary>
        Brush BackgroundBrush
        {
            get;
        }
        /// <summary>
        /// 工具啟動方法
        /// </summary>
        /// <returns></returns>
        FrameworkElement RunToolApplication();
    }

二、寫主窗體

所謂的主窗體,也就是各個模塊的承載器而已,因為各個模塊都是UserControl,需要窗體來承載。

需要的方法大概有兩個,尋找目錄的層級、創建相應的模塊。

1、尋找目錄層級

因為模塊最終要生成到一個位置,然後讓主程式去搜索,所以,需要一個搜索方法,去尋找

        /// <summary>
        /// 查找指定目錄下的所有末級子目錄
        /// </summary>
        /// <param name="dir">要查找的目錄</param>
        /// <param name="dirList">查找結果列表</param>
        /// <param name="system">是否包含系統目錄</param>
        /// <param name="hidden">是否包含隱藏目錄</param>
        public static void GetEndDirectories(DirectoryInfo dir,List<DirectoryInfo> 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時就要有兩個模塊,以此類推……

     /// <summary>
        /// 創建功能按鈕
        /// </summary>
        /// <param name="toolsInterface"></param>
        /// <returns></returns>
        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<DirectoryInfo> lastDirNameList = new List<DirectoryInfo>();
            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,額外加了一個類,用來實現第一部分提到的介面。

其中一個小工具在這:http://www.cnblogs.com/ZXdeveloper/p/5682230.html

基本東西不動,只是加了一個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還有很多不完善的地方,我會慢慢弄,後期會不斷的完善

DEMO


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...