1. 程式人生 > >C#框架程式設計動態載入模組(一)

C#框架程式設計動態載入模組(一)

本文系原創,轉載請註明出處:

在之前分享的部落格中,我已經實現了一個靜態載入的小框架,這個框架的模組已經在程式碼中確定,一旦生成程式,模組將無法改變。但在實際應用的大型專案中,我們更傾向於使用動態載入模組的框架,這樣對於專案的移植更加靈活和方便,因此今天我就來實現這個效果,和大家一起分享。先看結果展示:

大家看這個動圖是不是有種眼花繚亂的趕腳,沒辦法,CSDN只讓上傳5M的圖片。這次的案例會用到資料庫設計、資料庫程式設計、動圖載入控制元件、反射、系統ListView控制元件等等知識,實現比較複雜,所以我打算分兩部分來分享這個小框架的實現過程。

一、資料庫設計

因為專案比較簡單,並且為了便於使用,本案例中我使用了SQLite資料庫。在寫程式碼之前大家需要自行下載 System.Data.SQLite.dll 動態庫和 sqlitestudio 資料庫管理軟體,這裡就不做介紹了,如果找不到資源,可以給我留言。

資料庫的設計也比較簡單,我只添加了幾個必要欄位,主鍵、模組名稱、動態庫路徑、類名稱、使能、排序、時間戳、圖示,如圖所示:

以上設計就可以滿足我要實現的功能了,如有需要,大家可以自行擴充套件。接下來需要準備DBHelper.cs,網上版本也是一大堆,我這裡貼出一版供參考,看程式碼:

  public class SQLiteHelper
    {
        private static string dbFile = "myFrame.db";
      
        //生成連線字串
        private static string CreateConnectionString()
        {
            SQLiteConnectionStringBuilder connectionString = new SQLiteConnectionStringBuilder();
            connectionString.DataSource = @"Data/" + dbFile;

            string conStr = connectionString.ToString();
            return conStr;
        }

        /// <summary>
        /// 對插入到資料庫中的空值進行處理
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static object ToDbValue(object value)
        {
            if (value == null)
            {
                return DBNull.Value;
            }
            else
            {
                return value;
            }
        }

        /// <summary>
        /// 對從資料庫中讀取的空值進行處理
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static object FromDbValue(object value)
        {
            if (value == DBNull.Value)
            {
                return null;
            }
            else
            {
                return value;
            }
        }

        /// <summary>
        /// 執行非查詢的資料庫操作
        /// </summary>
        /// <param name="sqlString">要執行的sql語句</param>
        /// <param name="parameters">引數列表</param>
        /// <returns>返回受影響的條數</returns>
        public static int ExecuteNonQuery(string sqlString, params SQLiteParameter[] parameters)
        {
            string connectionString = CreateConnectionString();
            using (SQLiteConnection conn = new SQLiteConnection(connectionString))
            {
                conn.Open();
                using (SQLiteCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = sqlString;
                    foreach (SQLiteParameter parameter in parameters)
                    {
                        cmd.Parameters.Add(parameter);
                    }
                    return cmd.ExecuteNonQuery();
                }
            }
        }

        /// <summary>
        /// 執行查詢並返回查詢結果第一行第一列
        /// </summary>
        /// <param name="sqlString">SQL語句</param>
        /// <param name="sqlparams">引數列表</param>
        /// <returns></returns>
        public static object ExecuteScalar(string sqlString, params SQLiteParameter[] parameters)
        {
            string connectionString = CreateConnectionString();
            using (SQLiteConnection conn = new SQLiteConnection(connectionString))
            {
                conn.Open();
                using (SQLiteCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = sqlString;
                    foreach (SQLiteParameter parameter in parameters)
                    {
                        cmd.Parameters.Add(parameter);
                    }
                    return cmd.ExecuteScalar();
                }
            }
        }

        /// <summary>
        /// 查詢多條資料
        /// </summary>
        /// <param name="sqlString">SQL語句</param>
        /// <param name="parameters">引數列表</param>
        /// <returns>返回查詢的資料表</returns>
        public static DataTable GetDataTable(string sqlString, params SQLiteParameter[] parameters)
        {
            string connectionString = CreateConnectionString();
            using (SQLiteConnection conn = new SQLiteConnection(connectionString))
            {
                conn.Open();
                using (SQLiteCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = sqlString;
                    foreach (SQLiteParameter parameter in parameters)
                    {
                        cmd.Parameters.Add(parameter);
                    }
                    DataSet ds = new DataSet();
                    SQLiteDataAdapter adapter = new SQLiteDataAdapter(cmd);
                    adapter.Fill(ds);
                    return ds.Tables[0];
                }
            }
        }
    }

好了,以上我們的資料庫準備就基本OK了,下面看模組動態庫的準備。

二、準備載入模組

看過前兩期文章的朋友應該知道,我之前的模組是與主程式放在一個專案中的,但實際應用中通常模組是分開的,這裡我需要新建一個動態庫專案,將之前的程式碼檔案新增進去即可。沒有做過之前專案的朋友也一樣,在新建的動態庫專案中新建幾個模組介面即可。

如圖所示,ModuleLib 就是我的模組動態庫專案,裡面添加了3個模組,大家根據自己需要設計。

三、設計配置頁

先來看設計效果吧:

介面設計也非常簡單一個顯示的Table,三個增、刪、改按鈕和兩個確認、取消按鈕就OK了,關於這個Table,有很多第三方的控制元件可以支援,我用過的有FarPoint、Dev GridControl等等,非常方便,大家也可以自行設計。這裡為了簡單實現,儘量不要其他工具,我使用了系統自帶的 ListView 控制元件。

使用 ListView 控制元件需要配置以下幾個屬性:

1. Columns(表頭)

2. View (設定成Details樣式)

3. GridLines(表格線)

設定完這些,我們的介面設計就基本OK了,其他按鈕新增背景圖片和文字就可以了。在這個配置頁點選新增和編輯按鈕都會彈出一個編輯頁,下面需要設計一下這個介面。

四、設計編輯頁

先看效果圖:

這個介面就更簡單了,只需要幾個文字框、下拉框、按鈕即可,這裡就不做講解了。強調一下就是下拉框的 DropDownStyle 屬性要設定成 DropDownList,不允許編輯的狀態。

以上就完成了所有的介面設計,下一篇我會分享程式碼實現過程,歡迎繼續關注。

最後,給大家分享一下我的公眾號,在裡面會發一些技術文章以及部落格的更新推送,歡迎大家關注,再次感謝大家的支援!

                                                                                 掃描二維碼,關注我的微信公眾號