基本上我需要的是能够为我的应用程序添加新功能,而无需更新应用程序本身。
假设我有一个带有两个插件的应用程序。
应用程序有一个名为 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做到这一点吗?
答案 0 :(得分:4)
查看MEF,即http://mef.codeplex.com/的托管扩展性框架。它有很多内置支持插件组件的运行时发现。
答案 1 :(得分: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;
}
答案 2 :(得分:3)
查看MEF - http://msdn.microsoft.com/en-us/library/dd460648.aspx。即使您决定不使用它,您也可以看到如何实现和使用这种架构。
答案 3 :(得分:2)
了解托管扩展性框架MEF。