Once the problem of loading plugins is solved (in .NET through MEF in out case), the next step to solve is the communication with them. The simple way is to implement an interface and use the plugin implementation, but sometimes the plugin just needs to extend the way the application works and there may be a lot of extension points.
My question is about how to deal with that extension points. I've seen different ways of doing that but I'm not sure of the pros and cons of each one and if there are more and better ways to accomplish this:
Have you ever user one of the exposed approaches? Which one worked best for you?
And before you ask, our application is an extensible core (user, rola and content management) to build our client specific content centric web applications on top of that. Everything built on ASP.NET MVC.
A plug-in is a bundle that adds functionality to an application, called the host application, through some well-defined architecture for extensibility. This allows third-party developers to add functionality to an application without having access to the source code.
The plug-in architecture consists of two components: a core systemand plug-in modules. The main key design here is to allow adding additional features as plugins to the core application, providing extensibility, flexibility, and isolation of application features and customs processing logic.
Microservices are always a part of a larger distributed system whereas plugins are typically deployed on the same host often as dynamic modules inside the same process (even though for stability purposes modern applications prefer to run every plugin in a dedicated process).
The Eclipse platform is a framework for building IDEs, composed of a layer of UI APIs, beginning with the SWT (standard widget toolkit), rising to JFace (which provides more elaborate UI components such as dialogs), and culminating in the Workbench, which is synonymous with the Eclipse UI itself.
A key for your design decision is to analyze and get a clear picture of how different the plugins will be from eachother.
E.g. when dealing with static events, you will probably have to define each event as some form of token, enum, object etc. Having to define a new set of events for each plugin naturally works against your whole design, particularly in terms of loose coupling and reuse.
If your plugins are very different you might benefit from having a bus/messaging architecture since you in such case can introduce domains/categories of communication exchange, which the plugins can subscribe to. I.e. a range of events and messages can be in a certain interest domain. Note here that communication within a certain category can still utilize static events, so those two alternatives are not mutually exclusive.
Direct interfaces implemented by the plugins is in my experience the strictest approach of plugin architecture. Extending the plugin interface usually implies code modification at both plugin and provider. You need to have a solid general interface which you know your application can live on for quite some time.
It may be easier for you to deal with the design by breaking it down into two aspects - communication channel and protocol. Static event handling is a protocol issue, while bus-messaging and direct interfaces is a channel issue.
Generally I would say that the protocol is the hardest to design correctly from the beginning, since you may not have a solid feel for how general or specific you can draw the line.
EDIT: Lars made an important point in his comment - if your platform supports exceptions, you can centralize a lot of the error handling when using direct interfaces, relieving the plugins from having to handle errors that are generic and perhaps outisde their particular domain (e.g. "plugin load error", or "file open failed"). However, such benefits will seem to fade if you have to maintain interfaces each time you add plugins. Worst case is when the interfaces start becoming inconsistent along the way because you didn't realize what they should support from the beginning. Refactoring the entire interface design when a substantial amount of plugins already have been conceived is not an easy task.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With