Introduction

As applications grow, they tend to be harder and harder to maintain, despite the fact that most applications are more or less well designed from the start. This is usually because it's very easy to increase coupling when you need to add new features to your application. Plugins are a way to solve this by adding new functionality in small testable DLLs.

This example does not contain a lot of text describing everything, instead I'll just show you how to use the plugin system. If you have any thoughts, comment the article or visit the discussion board at Codeplex.

The Plugin System

The plugin system consists of three parts.

The Application

The application creates an instance of the PluginManager which is used to find and load plugins. The plugins are found by specifying a search string which contains directory information and wild cards for the files. You can specify the security settings (Evidence) that each assembly should be loaded with, which is perfect if you have different access levels for your plugins.

Application Interfaces

The second assembly contains the interfaces that the application exposes towards the plugins. This assembly exists since you may not want to send your entire application to third party plugin developers.

Plugins

And finally we got the actual plugin assemblies. Plugins can mark themselves dependent on other plugins. For instance, say that you have a newsletter plugin which generates and sends newsletters. The newsletter plugin needs an emailer which is specified in another plugin. The newsletter plugin can therefore mark itself as dependent on the emailer plugin, as a result of which the emailer will always be loaded before the newsletter plugin.

The Example

In this article, I'll demonstrate how to create a simple plugin.

First of all, we need to specify what the plugins should be able to do, and define which parts of the application are accessible from the plugins. All of this is added into a class library that will be sent to plugin developers.

Applications Shared Assembly

In this example, our application wants to let the plugins be able to register components and add menu items to the main application menu. By letting plugins register components, we got a quite flexible solution since plugins can use components registered by other plugins.

Update: Unloading Plugins

I've got some questions about how to unload plugins. I have no support for this in the plugin system and I'll try to explain why.

First of all, there is no way to unload assemblies (DLLs) from an appdomain (application). Period.

Solution: Appdomains and Remoting

Although there's a way around it: using a secondary appdomain for all plugins, this means that the plugins are in something that can be considered as an external application (each appdomain has isolated memory and an unhandled exception in the secondary appdomain will not affect the primary appdomain) which means that you need to use remoting to be able to communicate between the plugins and the main application.

Having all plugins in the secondary appdomain means that you can't unload a single plugin, you have to unload all of them. But hey, you can use one appdomain for each plugin, right? Well sure; if you can live with the performance hit.

Another Problem

Let's say that you have a plugin which provides an addressbook with contacts to the rest of the application. Do you really want to unload it? Let's say that the application (or any of the other plugins) contain references to some of your contacts, what happens to them if you unload that plugin?

Unloading stuff is much more complex than you might think.

Final Words

That's it. Let me know if there's something that you did not understand.

Comments and Discussions

I got the folowing message with the Red Circle and White X
dialog box (title: "Microsoft Visual studio")
------------------------------------------------------------------
"A Project with an output type of class Library cannot be started directly.

In order to debug this project, add an executable project to this solution
which references the library project.
Set the Executable project as the startup project."
------------------------------------------------------------------

my "starup project" is your "Fadd" project.

uaually I work with VC6.0 C/C++ programs and win 2000 SDK.
I will be gratefull if you will port this work to
a MSVC6.0++ demo (in a one button launch a debug == "F5").

TX
K.O.

p.s.
My goal is to create a minimal Mozila FireFox PlugIn,
and to create a minimal Worper to just download it (the DLL) from a server (like done with ActiveX OCX). The bare minimal neccesarry
c++ code to display "hello world" Text on the FireFox DviceContext
(or canvas I don't really care about it's name).

by the way did anybody used X-Plain SDK????
I think there is a sample for simple plugin.