2

I'm developing a system which needs to support customization via a plugins module. I'm coding against interfaces so that plugin code only needs to implement these interfaces in order to be able to plug into the system.

// for illustration purposes; not actual code
public interface IPluggable
{
    void Setup(PluginConfig c);
    bool Process(IProcessable p);
}

I read from configuration which plugins need to be loaded, where the assembly name and fully-qualified type name are specified.

<plugin assembly="Foo.Bar.PluginAssembly" type="Foo.Bar.Plugins.AwesomePlugin" />

Where the type Foo.Bar.Plugins.AwesomePlugin implements IPluggable and is contained in the assembly Foo.Bar.PluginAssembly.dll. With this information I proceed to create instances of the required plugins.

IPluggable plugin = (IPluggable)Activator.CreateInstance(assemblyName, typeName).Unwrap();

So my question is threefold:

  1. What would be a recommended pattern for a plugin system? Does the approach I'm taking make sense or are there any obvious flaws/caveats I'm missing?
  2. Is Activator.CreateInstance() a good choice for dynamically instantiating the plugin objects?
  3. How can I be more specific about the assembly to load and its location? Say, if I want to load plugins only from assemblies located in a .\plugins subfolder.
MarioVW
  • 2,225
  • 3
  • 22
  • 28

1 Answers1

4

Answers to your questions, in order:

  1. I like this and I use patterns like this when I need to write plug in components. Other people recommend using various frameworks - I know that MEF is very popular. But I find that using the .NET framework is easy enough for me, and learning the MEF framework is just another thing I need to learn and remember. It's probably worth a try but up to you.

  2. I've always used Assembly.CreateInstance, but the difference is probably not going affect you (Difference between Assembly.CreateInstance and Activator.CreateInstance?)

  3. You simply use the System.IO namespace. The DirectoryInfo class has a method that enumerates all the files matching a given pattern (presumably *.dll). For each match I'd use System.Reflection namespace to interrogate and find any types that implement your interface, and then CreateInstance.

Just on MEF, my opinion is this: if I were going to be using a large, manageable and flexible plug-in system on a number of systems or projects then I'd be very interested in it, leveraging the work that other people have done to save time and avoid common pitfalls.

If I were writing a very simple, one-off plug-in system and I know the basics of how to do so using the .NET framework, I'd skip the overhead of learning MEF and write the code. I could write a reasonable plug-in process in far less than an hour, but after downloading, referencing, attempting to configure MEF - I doubt I'd have anything to show for it.

Community
  • 1
  • 1
Kirk Broadhurst
  • 27,836
  • 16
  • 104
  • 169