Learning About Plug-In Architectures?
Pimpbot5000 queries: "I've searched high and low for a book/website/etc to get me up to speed on plugin architectures, but so far the pigeons aren't delivering. Where can a programmer go to learn about the different approaches, and their respective (dis)advantages? Most resources I've come across merely point you in the direction of creating plugins for existing projects, or quickly skip over the design phase and get straight to the 'and now you use dlopen()/dlsym() to...' part." I know quite a few plug-in architectures are language specific, but a resource that went over several schemes for each language would be a valuable thing for every coder's library.
A much better alternative is to offer a standard extension language, such as Python, Tcl, ELK, SIOD, Guile, lua, or even (the horrors) Perl. Now, most anyone of these languages have a plugin architecture, so if for any reason, you need native code speed, it can be done by writing a WHATEVERLANGUAGE-plugin.
The difficulty of creating a plugin architecture yourself over dlopen, is that you will most likely do it wrong at first try. A little bit less wrong on the second try, and so on... But each minor change you make to the plugin-architecture will probably break almost everything. So it's better to hand the problem off to the scripting-language-implementors...
Well, assuming that you absolutely must design a plugin system, lookin into some runtime aggregation systems (COM or CORBA depending on your platform and needs). That's basically with these techologies are for. (Well there are other uses as well, no flames on this please.)
Question: How many of you have worked on a project that's designed your own damned COM-like system?
Trees can't go dancing
So do them a big favor
Pretend dancing stinks!
You may design your app on top of objects like COM and then integrate a VBA like suite in it to allow everyone write their own plugin thingy in the application. Of course, this is a pure MS type solution but I believe the extensibility way of the Office package is great.
Integrating VBA is a bit costly, so you may try Microsoft Scripting Runtime (scrrun.dll) instead, its free. You will still be able to use application's object model from vbscript.
... but writing plugins is easy. People love to talk them up and make it sound like its some sort
of black magic but its nothing of the sort. All a plugin is is bunch of new functions your app can
call via function pointers (if using dlopen() etc) that have a standardised interface. Its not
rocket science , and in fact in a lot of cases its a damn site easier than having to use so called
common standards which sometimes throw so much overhead in that you wonder why you bothered.
In talking about a 'plug-in' architecture, from what viewpoint or for what purpose are you looking at the problem?
The first possibility I forsee is that you are developing an application which requires extensibility via third-party modules. In such a case that only design I am aware of (or rather, than I can think of at the moment) is to specify one or more APIs which the plug-in must implement, and then have the facility in your main application to register binary libraries. The application queries the libraries for the API(s) supported, and slots it in somewhere for use at the appropriate point.
The second possibility is that you are developing a plug-in architecture for a language, for others to use in a generic fashion. Your best bet is to study the way this is done in existing languages, and (as many other posters have said) don't do another plug-in architecture for a language that has one.
I had a third possibility in mind, but it seems to have been taken by a pigeon ;)
i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
Take a look at Bamboo, which is a plugin (or component) framework.
Bamboo home page
You define an interface (uh, "Plugin"?) which has a fixed API for your program to query it, and your provides some API so it can manipulate the program. In this API you might want to include a "bus" or event system that all plugins share so they can talk to other plugins without having to know about them ahead of time.
Bam. There's your plugin "architecture". What is the problem?
It's 10 PM. Do you know if you're un-American?
The key design element method is to make it object oriented, take the class's interface as your API, and bang, you've got a plugin interface.
A little info on my design. I was working on a driver to interface with a custom communication board. Well, we had an original version of the board that we abandoned, a later version which was really used, a test board for that one, and then one or two more.... Each board did communication with a companion board on another device.
My design was to abstract out the UART control, the low-level protocol, the FPGA control code and a couple of other things into seperate interchangable objects. These were objects, but implemented in C, since it wasn't possible to use C++ in the kernel on this platform. Each of those components were configured and plugged into the system at driver load time.
Now, I could have made this slightly different, by pulling out the individual components into seperate modules, loaded as needed, but in this case, that would have been overkill. But the principle is identical.
Back to your original question. I didn't have any books, or other guides to assist with the design. The design fell out of the original needs, after a reasonable amount of refactoring, and a bit of good architecture skill.
In your case, without knowing more details about the application, it's hard to help much. If this is for a general use application, your API will probably be insufficient the first time, so it would be worth your time to think about how you will handle large scale changes to the api. (Are you going to maintain backward compatibility? Are you going to support multiple APIs at the same time? Are you going to add additional specific interfaces over time?) But the core idea again is an OO design where the plug-in is just an object.
"Why should I be content to simply live in this world, when I, as a human being, can CREATE it?" - Oertel
Your question is very vague but I'll bite. First of all you need to understand the design solutions you can use. There are various ways of implenting plugins. Most of them depend on a component model like COM, JavaBeans or Corba. Essential is that you separate the consumer of functionality from the provider of functionality by specifying an interface.
You'll find that the more advanced types of plugin mechanisms are usually implemented in Java. This is no coincidence because Java has a few mechanisms built into the language that enable these mechanisms: reflection (i.e. discovering what methods/properties a class has at run-time), classloaders (load a class at run-time and let it run in a sandbox, destroy classloader to unload the class), dynamic linking (classes are resolved at run-time rather than compile time). An architecture that uses all of this is Jini. Often this is seen as a failed Sun project but the design behind Jini is still very cool.
A final word of advice: don't invent your own plugin mechanism but reuse existing ones.
Jilles
You have XPLC (shameless plug, that's the one I'm working on), CrystalSpace's SCF ("Shared Class Facility"), theKompany.com's Korelib, as well as others, including the previously mentioned Bamboo and Bonobo, but others like KDE's KPart/XPart, Mozilla's XPCOM and OpenOffice's UNO. You might even count Microsoft's .NET as well, if you want to.
Clemens Szyperski's book, Component Software - Beyond Object-Oriented Programming, is an excellent book on that subject.
jEdit's excellent (and very logical) plugin architecture is extensively described in the documentation. Check the site for more details.
Actually, TAO (The ACE ORB) has features to have dynamically loaded in-process servers, and to disable most of the features that makes other ORB's in-proc servers slower than COM or virtual C++ method invocation (stuff like method interception for example).
I wonder why you would choose CORBA if it was to disable all of the features that make it CORBA. Compatibility with other ORBs might be a reason, but I don't think that the kind of objects that you might want to have in-process and so on would be any good on other ORBs.
Some CORBA proponents will often claim that out-of-process is safer anyway, so that if you have a plugin crash, it won't take down your application, but most applications that do it that way becomes more or less confused after a plugin crashed, some to the point of crashing, so I don't see that being *that* much good anyway.
Make sure you leave yourself an option open so that you can screw the developers later, if necessary.
Rather than specifying a particular plugin model (COM etc.) it goes without saying that you should read and enjoy the classic "Design Patterns" (Gamma,Helm,Johnson,Vlissides pub Addison-Wesley, ISBN 0-201-63361-2).
This will give some insight into component architectures in general, and the way that different approaches are applicable to different modes of use.
I agree that you need to read "Design Patterns" for some ideas. In particular, I recommend in-depth study of the Strategy pattern as it seems tailor made to plug-ins.
Please mod this post only if you think others should/n't read this. I have enough ego^H^H^Hkarma. Thanks!