This is done in 3 simple steps.
Step 1. Creating universal interface for all plugins.
This should be done by creating a class library and add an interface. In this case, I'm adding 2 functions - one for initializing and one for calculating. Compile the class library.
public interface IPlugin
{
double Eval(double a, double b);
void Initialize();
}
Tip: Do not put the interface in a namespace. This would spare you some string symbols later ;)
Step 2. Creating a Plugin.
The plugin itself should be a class library, too. The main class in it, should implement the IPlugin interface from Step 1. Dafür, add a reference to the compiled class library and implement it.
public class Sum : IPlugin
{
public double Eval(double x, double y)
{
return x + y;
}
public void Initialize()
{
MessageBox.Show("Plugin loaded: " + Assembly.GetExecutingAssembly().FullName, "Plugin Message");
}
}
In this case, the initialize method shows a message box, and the Eval method - sums up two numbers.
Step 3. Adding the support to the application and loading the available plugins.
This happens in the main application. Let's say we have defined a directory for the plugins and it is the sub dir "plugins" of the main directory. We can search it up for any plugins.
First we define a collection, which will store all loaded plugins...
List<IPlugin> Plugins = new List<IPlugin>();
...and the load them...
string Path = Assembly.GetExecutingAssembly().Location.Substring(0, Assembly.GetExecutingAssembly().Location.LastIndexOf(@"\") + 1) + @"plugins\";
//getting all .dll files in plugins dir
string[] DLLs = Directory.GetFileSystemEntries(Path, "*.dll");
foreach (string DLL in DLLs)
{
Assembly AssemblyDLL;
try
{
AssemblyDLL = Assembly.LoadFrom(DLL);
foreach (Type objType in AssemblyDLL.GetTypes())
{
//Only look at public types
if (objType.IsPublic)
{
//Ignore abstract classes
if ((objType.Attributes & TypeAttributes.Abstract) != TypeAttributes.Abstract)
{
//See if this type implements our interface
Type objInterface = objType.GetInterface("IPlugin", true);
if (objInterface != null)
{
//instanciating
IPlugin PluginInstance = (IPlugin)AssemblyDLL.CreateInstance(objType.FullName);
//calling initialize method
PluginInstance.Initialize();
//adding it to the collection
Plugins.Add(PluginInstance);
}
}
}
}
}
catch (Exception e)
{
//Error loading DLL, we don't need to do anything special
System.Diagnostics.Trace.WriteLine(e.Message);
continue;
}
}
How to test it? Well, let's do some maths here :)
foreach(IPlugin plugin in Plugins)
{
MessageBox.Show(plugin.Eval(2d, 2d).ToString());
}
No comments:
Post a Comment