欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#反射實現(xiàn)插件式開發(fā)的過程詳解

 更新時間:2023年09月16日 08:55:07   作者:碼農(nóng)阿亮  
插件式架構(gòu),一種全新的、開放性的、高擴展性的架構(gòu)體系,插件式架構(gòu)設(shè)計好處很多,把擴展功能從框架中剝離出來,降低了框架的復(fù)雜度,讓框架更容易實現(xiàn),這篇文章主要介紹了C#反射實現(xiàn)插件式開發(fā),需要的朋友可以參考下

前言

插件式架構(gòu),一種全新的、開放性的、高擴展性的架構(gòu)體系。插件式架構(gòu)設(shè)計好處很多,把擴展功能從框架中剝離出來,降低了框架的復(fù)雜度,讓框架更容易實現(xiàn)。擴展功能與框架以一種很松的方式耦合,兩者在保持接口不變的情況下,可以獨立變化和發(fā)布?;诓寮O(shè)計并不神秘,相反它比起一團泥的設(shè)計更簡單,更容易理解。

項目介紹

書寫4個插件類庫,分別傳參實現(xiàn)“加減乘除”運算,調(diào)用插件的客戶端采用Winform窗體程序。

目標(biāo)框架: .NET Framework 4.6.1

項目架構(gòu)和窗體布局:

客戶端程序:

  • PluginApp:反射調(diào)用插件

插件描述:

  • PluginBase:規(guī)范插件的基類,定義抽象類,開發(fā)的插件的類需要繼承此類,代表遵守這個規(guī)范。
  • CustomPlugInA:實現(xiàn)加法的插件
  • CustomPlugInB:實現(xiàn)減法的插件
  • CustomPlugInC:實現(xiàn)乘法的插件
  • CustomPlugInD:實現(xiàn)除法的插件

代碼實現(xiàn)

插件基類

 /// <summary>
    ///插件基類
    /// </summary>
    public abstract class Base
    {
        /// <summary>
        /// 插件名稱
        /// </summary>
        /// <returns></returns>
        public abstract string Name();
       /// <summary>
       /// 插件描述
       /// </summary>
       /// <returns></returns>
        public abstract string Desc();
        /// <summary>
        /// 執(zhí)行方法
        /// </summary>
        /// <param name="param1">參數(shù)1</param>
        /// <param name="param2">參數(shù)2</param>
        /// <returns></returns>
        public abstract string Run(int param1, int param2);
        /// <summary>
        /// 版本 
        /// </summary>
        public string Version
        {
            get { return "1.0.0"; }
        }
    }

PlugInA

 public class PlugInA: Base
    {
        public override string Name()
        {
            return "PlugInA";
        }
        public override string Desc()
        {
            return "加法";
        }
        public override string Run(int param1,int param2)
        {
            return (param1 + param2) + "";
        }
    }
}

PlugInB

 public class PlugInB : Base
    {
        public override string Name()
        {
            return "PlugInB";
        }
        public override string Desc()
        {
            return "減法";
        }
        public override string Run(int param1, int param2)
        {
            return (param1 - param2) + "";
        }
    }

PlugInC

 public class PlugInC : Base
    {
        public override string Name()
        {
            return "PlugInC";
        }
        public override string Desc()
        {
            return "乘法";
        }
        public override string Run(int param1, int param2)
        {
            return (param1 * param2) + "";
        }
    }

PlugInD

 public class PlugInD : Base
    {
        public override string Name()
        {
            return "PlugInD";
        }
        public override string Desc()
        {
            return "除法";
        }
        public override string Run(int param1, int param2)
        {
            return (param1 / param2) + "";
        }
    }

客戶端核心代碼:

 public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
            dgrvPlugins.AutoGenerateColumns = false;
        }
        List<PluginModel> List = new List<PluginModel>();
        readonly string PlugInPath = Application.StartupPath + "\\PlugIns";
        /// <summary>
        /// 載入插件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btLoadPlugins_Click(object sender, EventArgs e)
        {
            if (!Directory.Exists(PlugInPath))
            {
                Directory.CreateDirectory(PlugInPath);
            }
            List.Clear();
            string[] files = Directory.GetFiles(PlugInPath);
            foreach (string file in files)
            {
                if (file.ToLower().EndsWith(".dll"))
                {
                    try
                    {
                        Assembly assembly = Assembly.LoadFrom(file);
                        Type[] types = assembly.GetTypes();
                        foreach (Type type in types)
                        {
                            if (type.BaseType.FullName == "PlugInBase.Base")
                            {
                                object obj = assembly.CreateInstance(type.FullName);
                                string name = type.GetMethod("Name").Invoke(obj, null).ToString();
                                string desc = type.GetMethod("Desc").Invoke(obj, null).ToString();
                                string version = type.GetProperty("Version").GetValue(obj).ToString();
                                List.Add(new PluginModel
                                {
                                    Name = name,
                                    Desc = desc,
                                    Version = version,
                                    type = type,
                                    Obj = obj
                                });
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }
            dgrvPlugins.DataSource = new BindingList<PluginModel>(List);
        }
        /// <summary>
        /// 打開插件目錄
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btOpenPluginDir_Click(object sender, EventArgs e)
        {
            Process.Start(PlugInPath);
        }
        /// <summary>
        /// 執(zhí)行選中插件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btExcute_Click(object sender, EventArgs e)
        {
            //獲取選擇的插件信息
            int index = dgrvPlugins.CurrentRow.Index;
            object obj = List[index].Obj;
            Type type = List[index].type;
            //參數(shù)
            object[] inParams = new object[2];
            inParams[0] =Convert.ToInt32( dgrvPlugins.CurrentRow.Cells[2].Value);
            inParams[1] = Convert.ToInt32(dgrvPlugins.CurrentRow.Cells[3].Value);
            object value = type.GetMethod("Run").Invoke(obj, inParams);
            MessageBox.Show(Convert.ToString(value),"結(jié)果",MessageBoxButtons.OK);
        }
    }

項目配置

插件生成配置

編譯生成項目的時候需要注意,此處的調(diào)用插件是通過反射調(diào)用.dll中類和方法,所以首先要找到這個.dll的文件,所以此處我們在Winform客戶端程序下建立一個存放類庫dll的文件 PlugIns ,在插件類庫項目生成后事件命令中,填入如下命令:

copy /Y "$(TargetDir)$(ProjectName).dll" "$(SolutionDir)\PlugIns"

以上命令代表,在項目的類庫生成后,將類庫copy到解決方案的路徑子文件夾 PlugIns ,也就是我們建立存放自定義插件的文件夾。當(dāng)然,如果不怕麻煩,每次生成后,手動復(fù)制到此文件夾也可以,直接復(fù)制到客戶端程序的 ..\bin\PlugIns 文件夾下。

插件路徑配置

全選這些類庫,把這些類庫設(shè)置為"如果較新則復(fù)制",這樣每次在編譯客戶端程序,如果自定義插件有更新,則同步會復(fù)制到 bin 目錄下

插件基類配置

插件基類提供了規(guī)范,需要在類庫的生成后事件,添加命令:

copy /Y "$(TargetDir)$(ProjectName).dll" "$(SolutionDir)\bin\Debug"

將生成的dll文件,拷貝到客戶端程序的 bin 路徑下

調(diào)用演示CustomPlugInA

CustomPlugInB

CustomPlugInC

CustomPlugInD

插件開發(fā)優(yōu)缺點

  • 把擴展功能從框架中剝離出來,降低了框架的復(fù)雜度,讓框架更容易實現(xiàn)
  • 宿主中可以對各個模塊解析,完成插件間、插件和主程序間的通信。
  • 插件開發(fā)的可擴展性,靈活性比較高,而且可以進行定制化開發(fā)。

缺點

  • 每一個插件被編譯成了dll,各模塊無法單獨運行,必須依托于主程序。
  • 修改插件時,由于生成的是dll,無法快速直觀的查看修改以及調(diào)試。
  • 每一個插件必須依賴于某一個規(guī)范。

到此這篇關(guān)于C#反射實現(xiàn)插件式開發(fā)的文章就介紹到這了,更多相關(guān)C#反射插件式開發(fā)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#中類與結(jié)構(gòu)的區(qū)別實例分析

    C#中類與結(jié)構(gòu)的區(qū)別實例分析

    這篇文章主要介紹了C#中類與結(jié)構(gòu)的區(qū)別,類與結(jié)構(gòu)是C#初學(xué)者比較輕易混淆的概念,本文加以實例說明,需要的朋友可以參考下
    2014-08-08
  • C# 實現(xiàn)顏色漸變窗體控件詳細(xì)講解

    C# 實現(xiàn)顏色漸變窗體控件詳細(xì)講解

    這篇文章主要介紹了C# 實現(xiàn)顏色漸變窗體控件詳細(xì)講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • C#實現(xiàn)數(shù)字轉(zhuǎn)換

    C#實現(xiàn)數(shù)字轉(zhuǎn)換

    這篇文章主要為大家詳細(xì)介紹了C#實現(xiàn)數(shù)字轉(zhuǎn)換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • Unity3D Shader實現(xiàn)貼圖切換效果

    Unity3D Shader實現(xiàn)貼圖切換效果

    這篇文章主要為大家詳細(xì)介紹了Unity3D Shader實現(xiàn)貼圖切換效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • C# 獲取程序集版本、文件版本

    C# 獲取程序集版本、文件版本

    C# 獲取程序集版本、文件版本的實現(xiàn)代碼。
    2009-09-09
  • 重溫C# clr 筆記總結(jié)

    重溫C# clr 筆記總結(jié)

    本篇文章是對以前學(xué)習(xí)C# clr做的一些筆記,現(xiàn)在拿出來和大家分享下,希望需要的朋友能參考一下
    2013-05-05
  • C#中計數(shù)排序算法的原理及實現(xiàn)

    C#中計數(shù)排序算法的原理及實現(xiàn)

    計數(shù)排序是一種線性時間復(fù)雜度的排序方法,主要通過統(tǒng)計元素出現(xiàn)的次數(shù)實現(xiàn)排序,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • C# 實現(xiàn)基于ADO.NET框架的DBHelper工具類(簡化數(shù)據(jù)庫操作)

    C# 實現(xiàn)基于ADO.NET框架的DBHelper工具類(簡化數(shù)據(jù)庫操作)

    ADO.NET是.NET框架中用于與數(shù)據(jù)庫交互的核心組件,提供了一套用于連接數(shù)據(jù)庫、執(zhí)行SQL查詢、插入、更新和刪除數(shù)據(jù)的類庫,包括SqlConnection、SqlCommand、SqlDataReader等,本文介紹如何使用DBHelper類封裝數(shù)據(jù)庫操作,以提高代碼的可維護性和復(fù)用性,感興趣的朋友一起看看吧
    2024-08-08
  • 使用C#進行音頻處理的完整指南(從播放到編輯)

    使用C#進行音頻處理的完整指南(從播放到編輯)

    在現(xiàn)代應(yīng)用程序中,音頻處理已經(jīng)成為不可或缺的一部分,無論是開發(fā)一個簡單的音頻播放器,還是構(gòu)建一個復(fù)雜的音頻編輯工具,C#都提供了豐富的工具和庫來實現(xiàn)這些功能,通過本文,我們將深入探索如何在C#中進行音頻播放、錄制、編輯、格式轉(zhuǎn)換以及音頻分析
    2025-04-04
  • c#連接mysql數(shù)據(jù)庫的方法

    c#連接mysql數(shù)據(jù)庫的方法

    這篇文章主要介紹了c#連接mysql數(shù)據(jù)庫的方法,需要的朋友可以參考下
    2014-04-04

最新評論