2011-10-26 24 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,托管扩展性框架。

相关问题