Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You're right that if you use a base class or interface in your core app, then you need to rebuild the app and all the plugins that use that class/interface if it changes. So what can you do about it? Here are some ideas (not necessarily good ones, but they may spark some thoughts) that you can mix &amp; match...</p> <ul> <li><p>Put the interfaces in separate shared assemblies, so you at least don't need to recompile the core app if an interface changes.</p></li> <li><p>Don't change any of your interfaces - keep them fixed in stone. Instead "version" them, so if you want to change the interface, you leave the old interface in place and just expose a completely new interface that extends or replaces the old API. This allows you to gradually deprecate old plugins rather than forcing an immediate global rebuild being required. This does tie your hands somewhat as it requires full backwards compatibility support for all the old interfaces at least until you know all your clients have moved on to newer builds of all their assemblies. But you can combine this with a less frequent "reinstall everything" release where you break backwards compatibility, clear out the defunct interfaces and upgrade all the client assemblies.</p></li> <li><p>Look for interfaces where some parts of the interface are not needed by all plugins, and break up some interfaces into several simpler interfaces, to reduce dependencies/churn on each interface.</p></li> <li><p>As you've suggested, convert interfaces into a runtime registration/discovery approach to minimise the churn on the interfaces. The more flexible and generic your interfaces are, the easier it will be to extend them without introducing breaking changes. For example, serialize data/commands to a string format, dictionary or XML and pass it in that form, rather than calling explicit interfaces. A data-driven approach like XML or a dictionary of name+value pairs is much easier to extend than an interface, so you can start supporting new elements/attributes while easily retaining backwards compatibility for clients that pass an older format to you. Instead of PostMessage(msg) + PostComment(msg) you could genericise the interface to a single method taking a type parameter: PostData("Message", msg) and PostData("Comment", msg) - that way it's easy to support new types without needing to define new interfaces.</p></li> <li><p>If possible, try to define interfaces that anticipate expected future features. So if you think you might one day add an RSS capability, then think about how that might work, chuck in an interface, but don't provide any support for it. Then if you finally get around to adding an RSS plugin, it already has a defined API to plug into. Of course, this only works if you define flexible enough interfaces that they are actually usable by the system when it is implemented!</p></li> <li><p>Or in some cases maybe you can ship the dependency plugins to all your customers, and use a licensing system to enable or disable their capabilities. Then your plugins can have dependencies on each other, but your customers can't utilise the facilities unless they've bought them.</p></li> </ul>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload