c#插件:访问母表单和函数
本文关键字:表单 函数 访问 插件 | 更新日期: 2023-09-27 18:12:29
我遵循了如何使应用程序支持插件的教程。一切似乎都工作得很好,但我需要的插件能够调用函数和访问变量在主要应用程序,而不仅仅是其他方式。我有一个http包装类,将监控网络使用等。插件将从母应用程序调用http包装器。
我怎样才能做到这一点?我需要定义一个类与所有可用的函数/变量?我还需要插件来生成GUI,以便用户可以为它设置一些设置。
这是我目前得到的:
主要用途:
namespace MainApplication
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
List<iPlugin> PLUGIN_LIST = new List<iPlugin>();
public void LoadPlugins()
{
// load plugins..
}
// how do I call this function from a plugin?!
public void HTTP()
{
// do some networking stuff..
}
private void Form1_Load(object sender, EventArgs e)
{
LoadPlugins();
}
}
}
插件接口:namespace PluginInterface
{
public interface iPlugin
{
string GetPluginName();
void callHTTP();
void SerVar(string var);
}
}
插件:
namespace MyPlugin
{
public class Main : iPlugin
{
string variable = "";
public string GetPluginName()
{
return "MyPlugin";
}
public void callHTTP(){
MainApplication.HTTP(); // call HTTP in main application
}
public void SerVar(string var)
{
variable = var;
}
}
}
另外,当我遵循教程时,插件接口是一个单独的项目,我必须在MainApplication和myPlugin中"添加作为参考"。这是否意味着我的应用程序和插件依赖于pluginInterface.dll?还是仅仅需要发展?如果它们依赖于运行时,我怎么能定义它在两个,我的应用程序和插件,这样我就不必使用额外的dll?希望这有意义,谢谢!
编辑:完整MainApplication代码
public interface iPlugin
{
string GetPluginName();
string GetInformation();
void SerVar(string var);
}
namespace MainApplication
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
List<iPlugin> PLUGIN_LIST = new List<iPlugin>();
public void LoadPlugins()
{
string path = Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName;
string pluginDir = Path.GetDirectoryName(path) + "''Plugins";
foreach (string s in Directory.GetFiles(pluginDir, "*.dll"))
{
// THIS LINE GIVES THE ERROR
Type[] pluginTypes = Assembly.LoadFile(s).GetTypes();
foreach (Type t in pluginTypes)
{
if (t.ToString().Contains("Main"))
{
iPlugin plugin = Activator.CreateInstance(t) as iPlugin;
PLUGIN_LIST.Add(plugin);
break;
}
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
LoadPlugins();
}
}
}
您可以采用的一种方法是定义一个接口,该接口包含您希望从母应用程序(例如称为IMother
)调用的所有方法,并使母应用程序实现此接口。
然后你可以更新IPlugin
有一个类似void SetMother( IMother mother )
的方法,当你加载每个插件时,你可以在插件上调用这个方法。这样,每个插件从一开始就有IMother
引用,并且可以在必要时调用方法。
关于您对plugininterface.dll的问题,是的,MainApplication和myPlugin都依赖于该dll(它不仅仅需要开发)。如果你想避免使用额外的dll(引用额外的dll通常不是问题),我会把插件接口放在与MainApplication相同的项目中。我不确定我是否理解你的布局,所以如果这不能回答你的问题,请添加更多的细节,你的项目/解决方案是如何配置的。
根据注释编辑:
我假设你的布局是这样的:
一个包含三个项目的解决方案文件
MainApplication的一个项目
myPlugin的一个项目一个插件接口项目。
可以将插件接口的代码文件移动到MainApplication项目中。这样MainApplication就不会依赖于其他任何东西。只需从插件接口项目中获取.cs文件并将其添加到MainApplication中。然后你需要从myPlugin中引用MainApplication,但这应该没问题。
这和别的没什么不同。给你的插件一个表单的引用。
至于.dll依赖,是的…插件和应用程序都是依赖的。但这并不是一件坏事。事实上,它非常非常好。我根本不会改变那一点架构
你必须创建一个新的接口,比如IHostPlugin,并通过这个接口公开你想在插件中使用的主表单的属性。在主表单类中实现接口,或者最好是在可以访问主表单的包装器类中实现接口。创建这个类marshalByref,并通过在你的插件接口上创建一个方法将它传递给你的插件,这个方法将这个主机接口作为参数,这样你的插件就有了一个对主机的引用。
你应该把这些接口放在一个单独的dll中,这样你就不会有跨应用程序域的类型不匹配。