Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Architecture for extension/plugin communication

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:

  • Events: Adding static events to all the stuff we want to make "extendable". For example, if I want to add custom validation for a User class, I can add a OnValidation static event handler and add events to it from the plugin when it's constructed.
  • Messaging: Having a bus and a messages. The plugin can subscribe to a particular message and do stuff when some other class publishes that message. The message should contain the context in which the plugin can work. In the validation case, the logic layer will publish a UserValidation message and the plugin will act when the message is received.
  • Interfaces: The host application is responsible of calling all the plugins that implement certain interfaces and give them the context of the current operation. In the case of validation, the plugin may implement a IValidator or IUserValidator with a Validate(object context) method.

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.

like image 217
Marc Climent Avatar asked Nov 18 '09 12:11

Marc Climent


People also ask

What is a plugin architecture?

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.

Which is a plugin architecture pattern?

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.

Are plugins Microservices?

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).

What is an eclipse in architecture?

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.


1 Answers

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.

like image 131
sharkin Avatar answered Sep 27 '22 23:09

sharkin