HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

WinForm plugin architecture

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
pluginarchitecturewinform

Problem

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 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 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
* Implem

Solution

You should use an interface instead of an abstract class:

public interface IPlugin {
    void Start();
    void Stop();
}


There are many reasons for this, as detailed in https://stackoverflow.com/questions/56867/interface-vs-base-class

I would also separate the plugin logic out of the form, and create a "PluginResolver" class to handle these concerns (This is where you hide the ugly reflection stuff you don't want to touch again).

In terms of the rest of the code, it's pretty basic, so not much to add.

In terms of creating a "plugin architecture" it's kind of a waste without using dependency injection (or a dependency resolver of some kind), because there's no obvious way for plugins to communicate with each other, unless they get coupled together (which defeats the whole point of the plugin architecture), instead by having a set of root services that can be injected into the particular plugins, you can have a disconnected way of giving them all access to say "the primary error logger".

Code Snippets

public interface IPlugin {
    void Start();
    void Stop();
}

Context

StackExchange Code Review Q#46790, answer score: 3

Revisions (0)

No revisions yet.