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.