I followed an tutorial how to make application support plugins. Everything seems to be working fine, but I need the plugin to be able to call functions and access variables in main application, not just the other way around. I have an http wrapper class that will monitor net usage etc.. for the main app. The plugin would call http wrapper from the mother application.
How can I accomplish this? Do I need to define a class with all the available functions/variables? I will also need the plugin to generate GUI, so that user can set some settings for it.
This is what I got so far:
Main Application:
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();
}
}
}
Plugin Interface:
namespace PluginInterface
{
public interface iPlugin
{
string GetPluginName();
void callHTTP();
void SerVar(string var);
}
}
The Plugin:
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;
}
}
}
Also, when I followed the tutorial, plugin interface was a seperate project, which I had to ‘add as reference’ in both MainApplication and myPlugin. Does that mean that my application and plugin are dependent on pluginInterface.dll? or it is just needed for development? if they’re depended in runtime, how can I define it in both, my app and plugin, so that I don’t have to use extra dll? Hope that makes sense, Thanks!
EDIT: Full MainApplication code
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();
}
}
}
One approach you could take is to define an interface that contains all the methods that you would like to call from the mother application (called say
IMother), and make the mother application implement this.Then you could update
IPluginto have a method likevoid SetMother( IMother mother )and when you load each plugin you could call this method on the plugin. That way each plugin would have theIMotherreference from the beginning and could call methods as necessary.Regarding your question on plugininterface.dll, yes, both MainApplication and myPlugin are dependent on that dll (it is not just needed for development). If you want to avoid using an extra dll (having references to extra dlls isn’t generally an issue) I would put the plugin interface in the same project as MainApplication. I’m not sure if I’m understanding your layout though, so if that doesn’t answer your question please add more details as to how your projects/solution is configured.
EDIT BASED ON COMMENT:
I assume your layout is something like the following:
One solution file that contains three projects
One project for MainApplication
One project for myPlugin
One project for the plugin interface.
You could move the code files for the plugin interface into the MainApplication project. That way MainApplication would not be dependent on anything else. Just take the .cs file from the plugin interface project and add it to MainApplication. You would then need to reference MainApplication from myPlugin, but that should be ok.