I have been developing this plugin architecture, mostly for fun and education, its a simple Winform with some plugin logic and two plugins, i want to know if there is a better way of doing it.
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Plugin_architecture
{
public partial class Form1 : Form
{
// -----------------------Plugin logic ----------------------------------
private static IEnumerable<Type> getDerivedTypesFor(Type baseType)
{
var assembly = Assembly.GetExecutingAssembly();
return assembly.GetTypes().Where(baseType.IsAssignableFrom).Where(t => baseType != t);
}
public void invokePlugin(object sender, EventArgs e, string pluginIdentifier) {
Type type = Type.GetType(pluginIdentifier);
object instance = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("start");
method.Invoke(instance, null);
}
public void registerPlugins() {
// Register plugins at application startup
IEnumerable<Type> plugins = getDerivedTypesFor(typeof(Plugin));
foreach(Type plugin in plugins) {
LinkLabel pluginLabel = new LinkLabel();
pluginLabel.Text = plugin.ToString();
pluginLabel.Click += delegate(object sender, EventArgs e) { invokePlugin(sender, e, plugin.ToString()); };
pluginContainer.Controls.Add(pluginLabel);
}
}
// --------------------------------------------------------------------------
public Form1()
{
InitializeComponent();
registerPlugins();
}
}
}
Plugin.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
abstract class Plugin
{
/*
* Base class for plugins
* Implement the start method and add any functionality you want. The start method will be
* called each time the plugin is started. Use the stop method to do any nessesary cleanup.
*/
//public void init() {
// // Initialize plugin
//}
//public void register() {
// // Register plugin in application
//}
abstract public void start();
abstract public void stop();
}
ServicePlugin.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
class ServicePlugin : Plugin
{
override public void start() {
const string message = "Yeahh! Plugins!!";
const string caption = "Plugins!";
var result = MessageBox.Show(message, caption,
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
override public void stop() {
}
}
ClientPlugin.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Plugin_architecture.Plugins.ClientPlugin;
class ClientPlugin : Plugin
{
override public void start() {
Client frm = new Client();
frm.Show();
}
override public void stop() {
}
}
Client.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Plugin_architecture.Plugins.ClientPlugin
{
public partial class Client : Form
{
public Client()
{
InitializeComponent();
}
}
}
The code works great, and should compile without problems.