GSS 技術部落格
在這個園地裡我們將從技術、專案管理、客戶對談面和大家分享我們多年的經驗,希望大家不管是喜歡或是有意見,都可以回饋給我們,讓我們有機會和大家對話並一起成長!
若有任何問題請來信:gss_crm@gss.com.tw
字體大小: +
2 分鐘閱讀時間 (439 個字)

如何在 .net上實作具有 plugin 機制的系統

 先介紹一下 Strategy Pattern

  在介紹如何實作 Plugin 機制之前先介紹一下 Strategy Pattern,Strategy Pattern 為 Design Pattern 其中的一個 Pattern, 這個 Pattern 會透過一個 Interface 定義一系列的演算法,每一個演算法都有各自不同的實作方式,而這些演算法可以相互替換。因此 Plugin 機制會透過這個 Pattern 來實現。

  Plugin 機制的系統結構

  • 系統架構總共分為三大專案

    • Main Program

      • 主系統
      • 讀取 Plugin 檔案,透過 IPlugin 定義的 Method 執行各個 Plugin 的實作
      • 透過 Assembly Reflection 的方式實現
      • Plugin 檔案在不同的程式語言有各自檔案格式,例如:C# 為 DLL檔、Java 為 JAR檔
    • IPlugin

      • Plugin 介面
      • 定義相關的 Method 提供給各個 Plugin 實作,同時也提供給主系統使用
    • lPlugin A, Plugin B ...

      • 繼承 IPlugin,並且實作相關的 Method

  McMaster.NETCore.Plugins 介紹

 

  • Github 連結

  • 為一個 .NET Core 開源套件

  • 目前只有提供 .NET Core 使用

  • 提供的功能:

    • 讀取 DLL 檔 (Assembly Reflection)

    • 提供 Plugin Unloaded

      • 這個功能需要 .NET Core 3.0 以上的專案
    • 處理 Share Library 問題

      • Plugin之間所參考的套件版本不同的問題

 McMaster.NETCore.Plugins 在 Share Library 處理的做法

 1. 不使用 Share Library

Plugin 和主程式皆不相互影響,各個 Plugin 使用各自參考的套件版本,但需要樣將參考的套件的DLL檔放到 Plugin 同一個目錄底下

 2. 使用 Share Library

 Plugin 統一使用主系統使用的套件版本,Plugin 同一層目錄可以不用放參考套件的 DLL檔

McMaster.NETCore.Plugins 實作

套件安裝

Install-Package McMaster.NETCore.Plugins 

 套件使用

using McMaster.NETCore.Plugins;
using System.Linq;
using System.Reflection;

public class MyPluginLoader 
{
    // pluginAssemblyPath: Plugin 的 DLL檔路徑
    // pluginClassName: 要呼叫的 Plugin 的類別名稱 (包含 Namespace)
    public IPlugin LoadPlugin(string pluginAssemblyPath, string pluginClassFullName) 
    {
        // 透過 PluginLoader 讀取 DLL檔
        var loader = PluginLoader.CreateFromAssemblyFile(assemblyFile: pluginAssemblyPath,
                                                         sharedTypes: new[] { typeof(IPlugin) });

        // 取得實作 IPlugin 的類別 & 要呼叫的 Plugin 類別
        Type type = loader.LoadDefaultAssembly()
                          .GetTypes()
                          .Where(t => typeof(IPlugin).IsAssignableFrom(t) && 
                                      !t.IsAbstract &&
                                      t.Name == pluginClassFullName)
                          .FirstOrDefault();
                          
        // 建立 Plugin Instance
        var myPlugin = (IPlugin)Activator.CreateInstance(type);
        
        return myPlugin
    }
} 
×
Stay Informed

When you subscribe to the blog, we will send you an e-mail when there are new updates on the site so you wouldn't miss them.

PWA - IndexDB Implement
AspNetBoilerplate(ABP) - 外部登入

相關文章

 

評論

尚無評論
已經注冊了? 這裡登入
2026年4月14日, 星期二

Captcha 圖像