Message Passing in a Plug-in Framework
I've been running a couple of coding projects at home over the last couple of months, one of which is a personal finance program. I've used this as an experiment in new technologies (mainly .Net 3.0/3.5 stuff, including LINQ and WPF/XAML), as well as one in architecture and design patterns. The program is based around a plug-in architecture and the time has come to consider message-passing between plug-ins; for example, I need non-storage plug-ins to inform storage plug-ins when their data has changed, and what data has changed, so that the storage plug-ins can schedule these changes for serialisation to their storage format (be it an SQLite database, an XML file, or whatever).
The plug-in framework enables the loading of different classes of plug-ins, each with their own interface; for example, there is a class of plug-in for accounts, one for reports, two for file type support (import and export), etc. The framework provides the environment for loading and interacting with plug-ins, the necessary interfaces etc. for coding plug-ins against, managing of preferences and logging, etc., etc., etc., ad nauseam. It is a mediator and arbitrator between the plug-ins which provide the real meat of the application.
The project has now got to the point where I need to be able to pass messages around the framework, between plug-ins. The immediate solution that sprung to mind was the classic publish/subscribe model, so I duly looked into the Observer pattern, a manual implementation of publish/subscribe. This feels wrong in that it doesn't seem to provide a way for plug-ins to register new notification types (e.g., BeforeDataChange => "if you need to do something before you update your data, now is your chance") under defined categories of events, let alone define new categories. Solution #1 scrapped.
I thought I'd cracked it with my next possible solution, the Blackboard pattern, which is based around the idea of cops solving a crime; the policemen post different bits of information and evidence on a central blackboard and infer further information in the form of links and relationships between the items. This approach has historically been used to great effect in AI systems, such as OCR, speech recognition, etc., but didn't feel quite right for this scenario. However, I didn't like the idea of posting up all these changes for the entire application to see, when the message was intended for a particular set of recipients. Solution #2 scrapped.
So I revisited publish/subscribe, this time with .Net events. A .Net event is just a special case of the .Net idea of a delegate, or callback, method; it is an analogue to a function pointer for those of you in the C++ world, although it has to be said that this metaphor quickly breaks down as delegates also have an object representation that makes the more than just pointers. They give you multi-casting for free, as callback methods are assigned to delegates using the "+=" operator, building a list of methods invoked by calling the delegate. I thought maybe I could leverage the object-ness of delegates to implement categories via inheritance, but it turned out this wasn't possible (probably A Good Thing™).
Events don't seem to play nicely with my proposed model of using a broker class to mediate the publications and subscriptions. The broker should store a list of published actions, and plug-ins should be able to retrieve the list of published actions in order to subscribe to a subset of them. I may need to go down the path of a custom solution (such as porting the Message Manager from my fourth-year project), which is not very DRY, but should give me a greater level of decoupling in the architecture than I think an events-based model will give me.
Coding:
- 1975 reads
Comments
Ben Hymers (not verified)
25 June 2008 - 3:11pm
Permalink
There was some open source
There was some open source project, "Stereoshite" or something like that, which did message passing quite well. The guy who wrote it (Ben Hammers? Homers? I can't remember) was brilliant, anyway.
Look into signals and slots as an implementation of message passing/events. Every conversation I have about messaging or events leads to signals and slots.
What language are you using for this application? I read it assuming C# since you mentioned .NET, but of course you're more 'webby' than that ;)
alastairs
29 June 2008 - 6:25pm
Permalink
C# it is...
...sorry to disappoint!
I'm not all that "webby" these days, despite the fact that I'm working on a website! All my work is in Java or C#, generally (I've even done a smidgeon of C++), and the back-end of the website is not very "webby" at all. No databases or anything.
I do like the Stereoshift Message Manager, it looks like an elegant solution to the problem. I'm trying not to go down the more bespoke route that the Stereoshift Message Manager took, though, as there's this event mechanism built into .NET that should do the notifications for me, but I keep hitting brick walls. It might be because I'm doing something wrong somewhere... Maybe something like introducing a third-party mediator between plug-ins to handle the subscriptions when event subscriptions are supposed to be direct.
-- Alastair
Add new comment