Add a plugin system to your .NET application
Roy Osherove wrote a cool article (with code) on implementing a plugin system in C#.
The architecture that is described is simple and clear. It also serves as a nice sample for having custom configuration handlers and loading/instanciating classes at runtime (via the Activator).
Update: Roy posted a second article on the topic of plugins.
SharpDevelop Add-Ins
Check out this introduction paper from the SharpDevelop team on the SharpDevelop Open Development Architecture, which is a richer (but harder to understand) add-in system.
They also published a book (Dissecting a C# Application: Inside SharpDevelop) with two very detailled chapters on their add-in management, with annotated code. A couple other chapters are even available online for free (one on the Windows Form designer and one on the Language Bindings).
I read the chapter from their book twice already to understand how all the pieces fit together. Here is my attempt to describe the gist from the architecture, as I understand it (standard disclaimer ;-).
Basically, each add-in is described by an XML file. These XML files are searched in sub-directories and loaded at startup. The XML file can specify for some assemblies to be loaded, which will be scanned for "codon" definitions (a codon is a class describing some extension, like a menu item, a compression strategy, a language binding,...) using Reflection. The XML file then lists the codons (and their configuration) that it needs instanciated. The resulting initialized codon objects are placed in a tree structure.
Once the AddInTree is loaded with all the input from the XML files, the codons classes are "activated" by calling a recursive BuildItem method on them. The BuildItem returns an object (who's type is up to the codon coder) and takes an array of such objects as an input (the result of the BuildItem on all the current node's childs). This allows an add-in to support being extended by sub-add-ins.
The BuildItem method may for example generate menu items (and sub menus) in the IDE with some event handlers. It could also register a service or even do nothing (in which case the codon just sits there in the tree, waiting for somebody to look it up, as it might be the case for a compression strategy).
Codon classes can be re-used with different configurations, like the MenuItem that mainly needs a label and an "action" class (that needs to inherit from IMenuCommand in order to handle the clicks on the menu entry).
This system allows add-ins to be included without registering them in a centralized config file and their respective assemblies to stay isolated. Installing an add-in is then just a matter of copying a directory over and starting the application.
The core classes for this add-in system are cleanly isolated in the SharpDevelop source tree, so it should be possible to re-use it in other projects.
Visual Studio.Net Add-Ins
I wish I could see the internals of the Visual Studio add-in architecture ;-) But in terms of implementation, the set of hooks for add-ins in VS.net is described by the Extensibility.IDTExtensibility2 interface.
Here is the entry point on MSDN to manipulating the development environment.
They also have samples, like this VS.NET 2003 add-in walkthrough.
Very good...very good material you have here...
Thanks a lot for your help.
Posted by: Cyrus (August 27, 2004 12:22 PM)