So You Want To Build A Plug-in Enabled Application?
Like the title of this post asks, so you want to build a plug-in enabled application? As a developer I’ve run across this scenario at different times during my career and every time it pops up, I always seem to know a little more than I did the last time I approached this problem. This post is about helping you think about a plug-in application of your own. First, let’s look at scenarios where you would want to have a plug-in architecture.
It’s Plug-in Time!
Ok before you use this hammer, you first have to know what you’re swinging at. Below are common usages for a plug-in application, but certainly not all the scenarios.
- Job Scheduler
- Content Management System or Blog Engine
- Integrated Development Environment (IDE)
- Highly Customizable Software Products
- And Much More!!
So those are a few ideas of where a plug-in architecture could be helpful, now lets look at what you should keep in mind when developing a plug-in based application.
Shells Aren’t Just For Turtles
For any good plug-in architecture to work it will need a solid shell. A shell is that part of the architecture that orchestrates and manages all those plug-ins you want to work together. Below are some features to keep in mind when creating a shell. They are in no particular order of importance.
- Service Location : The shell should be capable of finding services, and giving a plug-in the ability to find a service as well.
- Strong Exception Handling: The shell shouldn’t trust any plug-in to do its job. If the plug-in is bad, that doesn’t mean the shell has to freak out.
- Logging: The shell should let you know what it’s doing, and what it hopes to do if all goes well.
- Instrumentation: The shell should let you enable and disable a plug-in. This could be as simple as deleting a configuration or building an admin tool.
- Abstract: The more abstract your shell is, the more the responsibility of functionality falls on your plug-in. This is a good thing.
- Orchestration Theme: The shell has a theme to its orchestration i.e. executing a scheduled job, displaying web pages, etc.
- Event Aggregation: Things happen in plug-ins, but how are you going to let other plug-ins know or the shell for that matter.
Keeping some of the things mentioned above in mind will help keep you on the right path when building the shell, but what about those plug-ins? That’s the next step.
It’s in the Contract
There are usually two approaches to allowing developers to create a plug-in. The one way is through inheritance. The developer inherits from “PluginBase” that has methods he needs to override. From my experience having a “PluginBase” has always lead to more headache than it is worth. I found that functionality would be inherited into a plug-in that I didn’t necessarily want. Any functionality I wanted in all and every plug-in usually ended up finding a better home in the shell.
The second way to allow developers to create a plug-in is through interfaces/contracts. Interfaces give developers a better understanding of what they need to implement, and with interfaces there is more room for composition. Remember .Net does not support multiple inheritance but it does allow for multiple interfaces. This allows a developer to build very specific plug-ins by only implementing the interfaces that make sense. i.e. a plug-in that has a UI might implement a UIPlugin contract, where as a plug-in that doesn’t have a UI would just neglect implementing that interface.
The Right Technology Stack
The success of your architecture depends on the technology you choose. As like any other development project, you have to choose the right tools for the job. If your plug-in architecture needs to span across networks and live on multiple machines, storing your configuration in files might not be a good idea. If your plug-in architecture exists on one machine, then you probably don’t need WCF or any other kind of remoting. That being said, you should build your architecture so that you can change major parts of your architecture without major effort or overhaul of the entire architecture. Using patterns like IoC can help make this less earth shattering.
Plug-in Architectures are very powerful. They can be the solution to a lot of problems, but I would not advise going down this route if you just want to flex your development muscles. A good exercise to do is to whiteboard the different aspects of your architecture. Draw a large circle in the middle of the board and label it “Shell,” then draw little circles connected to the larger circle for each plug-in. This will help you visualize what your plug-ins are, and what your shell needs to accomplish for these things to work together. Once you realize what the shell is and more importantly is not, you will find your plug-in architecture will fall right into place.
I know these kind of projects can be really fun