寫 c/c++ 的時候,可以用 dlopen 來讀入 .so/.dll 檔當作 plugin 用,寫 perl 的時候用 require 就可以把另一個 perl module 讀到記憶體,elisp 也有類似的用法,.NET 則提供了 System.Reflection.Assembly 類別來處理這樣的事。
首先為了統一 Plugin 的介面,我們可以定義幾個 Plugin 專用的 interface:
// PluginInterfaces.dll
namespace Plugin.Interfaces
public interface IPlugin
Calculate (input: int) : int
然後 Plugin 的實做寫在另一個 Assembly:
// Plugins.dll
using Plugin.Interfaces
namespace Plugin.Test
public class Test1 : IPlugin
public Calculate (input: int) : int
input * 2
public class Test2 : IPlugin
public Calculate (input: int) : int
input + 3
然後主程式就可以把這些 plugins 動態的讀近來:
// Run.exe
using System
using System.Reflection
using Plugin.Interfaces
public module R
public Main (args: array[string]) : void
def p = Assembly.LoadFile (args[0]).CreateInstance (args[1]) :> IPlugin
Console.WriteLine (p)
Console.WriteLine (p.Calculate (100))
實際執行的結果:
$ ncc PluginInterfaces.n -out:PluginInterfaces.dll -target:library
$ ncc Plugins.n -ref:PluginInterfaces.dll -out:Plugins.dll -target:library
$ ncc Run.n -ref:PluginInterfaces.dll -out:Run.exe
$ ./Run.exe Plugins.dll Plugin.Test.Test1
Plugin.Test.Test1
200
$ ./Run.exe Plugins.dll Plugin.Test.Test2
Plugin.Test.Test2
103
嗯,大概就是這樣 😉