2011-10-26 42 views
2

基本上我需要的是能夠將新功能添加到我的應用程序,而無需更新應用程序本身。C#製作應用程序支持插件,運行多個實例,可能嗎?

可以說我有兩個插件的應用程序。

應用程序有一個函數叫做generateNumber();

Plugin_1將有以下代碼:

void init(){ } 

int exec(){ 
    int number = HOST_APPLICATION.generateNumber(); 
    number = number * 2; 
    return number; 
} 

Plugin_2將具有相同的結構,只有不同的功能:

void init(){ } 

int exec(){ 
    int number = HOST_APPLICATION.generateNumber(); 
    number = (number * 10) + 13; 
    return number; 
} 

我需要每個 '插件' 的多個實例同時運行(每個都在它自己的線程中),所以總共有20個線程同時運行。該代碼將是這樣的:

主要用途:

void init_plugins() { } 

void execute_plugins(){ 
    for(int i=0; i<plugins.count; i++){ 

     for(int z=0; z<10; z++){ 
      Thread t = new Thread(plugin_research); 
      t.start(plugins[i]); 
     } 

    } 
} 

void plugin_research(PluginStructure Plugin){ 
    Plugin.init(); 
    int return_val = Plugin.exec(); 
    // do something with return_val 
} 

我還需要託管應用程序調用插件的功能(該結構將所有插件一樣)和插件能夠調用主機應用程序的功能。

每個插件都有不同的配置控件。我需要在一個地方顯示配置,但同時多次調用插件功能(使用線程)

這可能嗎?什麼是實現這一目標的最佳方式?我可以用iPlugin做這個嗎?

回答

3

基本上每個插件都應該從基類中派生出來暴露你想要的方法。

public abstract class BasePlugin 
{ 
    protected int number; 

    public abstract void init_plugin(); 
    public abstract int exec(int number); 
    public BasePlugin(int number) 
    { 
     this.number = number; 
    } 
} 

然後,你必須

public class Plugin1: BasePlugin 
{ 
    public override void init_plugin() 
    { 
    } 

    public override int exec(int number) 
    { 
    } 
} 

在您的應用程序,你可以創建插件,並將其保存在一個列表

List<BasePlugin> list = new List<BasePlugin>(); 
list.Add(new Plugin1(generateNumber())); 
BasePlugin p2 = new Plugin2(generateNumber()); 
p2.init_plugin(); 
list.Add(p2); 

,並加載的插件不管你請說。
或(如我從你的編輯問題看),你可以爲每個插件創建線程...

要加載的插件,你可以使用函數像這樣:

public static List<T> GetFilePlugins<T>(string filename) 
{ 
    List<T> ret = new List<T>(); 
    if (File.Exists(filename)) 
    { 
     Type typeT = typeof(T); 
     Assembly ass = Assembly.LoadFrom(filename); 
     foreach (Type type in ass.GetTypes()) 
     { 
      if (!type.IsClass || type.IsNotPublic) continue; 
      if (typeT.IsAssignableFrom(type)) 
      { 
       T plugin = (T)Activator.CreateInstance(type); 
       ret.Add(plugin); 
      } 
     } 
    } 
    return ret; 
} 
public static List<T> GetDirectoryPlugins<T>(string dirname) 
{ 
    List<T> ret = new List<T>(); 
    string[] dlls = Directory.GetFiles(dirname, "*.dll"); 
    foreach (string dll in dlls) 
    { 
     List<T> dll_plugins = GetFilePlugins<T>(Path.GetFullPath(dll)); 
     ret.AddRange(dll_plugins); 
    } 
    return ret; 
} 
+0

謝謝Marco!你能告訴我什麼時候我在C#中開始新項目,我應該選擇什麼,Win Application for plugin?我也需要Gui來進行配置。每個插件都有自己的配置。 – user1015551

+0

@ user1015551:對於每個插件,您可以選擇Windown Form;然後在項目屬性轉到應用程序選項卡,並選擇「類庫」作爲輸出類型 – Marco

+0

@ user1015551:正如你可以從我的代碼看到的,不要從插件調用'HOST_APPLICATION.generateNumber();',但傳遞一個新的生成號碼每個插件與它的構造函數。這樣你從你的應用程序拆分插件..否則這是有單獨的插件的原因? – Marco

4

查找到MEF,託管的可擴展性框架在http://mef.codeplex.com/。它有很多內置的支持運行時發現插件組件。

2

查看MEF,託管擴展性框架。

相關問題