Andrey Rubshtein
Andrey Rubshtein

Reputation: 20915

How to use version numbers for interface in application with plugins?

I want to write a program that will allow writing plugins for it.
The program will contain SDK with some DLLs libraries that will facilitate the development of the plugins.

However, I am pretty sure that over time the SDK will change, so some kind of version number for the SDK and plugins is needed. The SDK consists of many DLLs.

Also, I don't want that the plugin developer will be able to forget to do something that is needed for the mechanism.

I can think of two ways:

So, I am not sure about how to do both.

Do you have any idea?

Upvotes: 1

Views: 405

Answers (3)

Eugen Rieck
Eugen Rieck

Reputation: 65274

As requested by @Andrey this is an elaboration of my comment to the OQ:

Plugins (as in plugin assemblies) will most commonly contain a classm, that implements an interface such as IMyPlugin

In most cases this inteface will need to have a method like InitPlugin(), that allows the plugin to set up its structures etc, i.e. to initialize.

This InitPlugin() will in itself want most often call something like RegisterPlugin() in the main program to register its functionality with the application. This is typically also achieved with an interface such as IMyPluginHost.

Now as long as you keep these interfaces so generic, that they themselfes don't need to change, you can easily add version handshake with this sequence:

public interface IMyPluginHost
{
  public int RegisterPlugin(int FunctionalityGroup, object WorkerBee, int MinSDKVersion, int MaxSDKVersion);
  ... //Whatever you need to allow the plugin to call into the app
}

public interface IMyPlugin
{
  public int InitPlugin(IMyPluginHost myhost); //Return value is hust an error code
  ... //Whatever you need to allow the app to call into the plugin
}

Now when the app decides to load a plugin, it will create its internal plugin host class that implements IMyPluginHost, then physically load the plugin, get an IMyPlugin to its class and call

((IMyPlugin)pluginClass).InitPlugin(this)

The plugin can now cycle its functionality groups (which groups there are depends on your app - if it is e.g. an image manipulation app, there might be functionality groups such as Filter, FileTypeImport, FileTypeExport, Brush, ... each with their interface) and for each instantiate a worker object, then call

host.RegisterPlugin(FunctionalityGroup, WorkerBee, MinSDKVersion, MaxSDKVersion);

with host being the IMyPluginHost it got as as anrgument to InitPlugin().

So if the plugin is built only against SDK V5 MinSDKVersion and MaxSDKVersion will both be 5. But if a smart plugin can handle SDK Versions 2-5 MinSDKVersion will be 2 and MaxSDKVersion will be 5. This allows one plugin to work with different versions of your app (and thus SDK)

The app itself also has a range of SDK versions it supports, say 3-6. So in this case the call to RegisterPlugin() would return 5, as this is the highest SDK version that both partners support. Again this gives your app a way to support older plugins, so that upgrading your app doesn't break all third-party plugins.

Negative return values for InitPlugin() would be errors.

After this is done, the plugin has a reference to the host and knows about what it can expect from it in terms of SDK version and vice versa.

Upvotes: 2

Tigran
Tigran

Reputation: 62246

I would no introduce a versioning concept at all. If you think what the Host needs:

  • possibility to locate and load plugins
  • posibility to interact with them, by exposing a features to the plugins or recovering from them.

How to manage the dev changes in SDK?

First of all: all changes have to be as much as it possible back compatible.

What if it's btw not possible?

Well, the Host searches for exposed functionality inside a loaded plugin, if it fails to find, it leads to 3 possible conclusions.

  1. Plugin is written for newer version of Host but used by old one

  2. Plugin is written for older version of Host but used by newer.

  3. it's not a valud plugin.

For sure, you can include a required Host version like a attribute on the MainClass of your plugin and Host can search for it, this can help for easy identification of possible version conflict. Why possible, cause the version could be different but the architecture can be pretty reliable and no need to plugin supplier to change something inside it.

Hope this helps.

Upvotes: 3

linkerro
linkerro

Reputation: 5458

Create an abstract class that all plugins have to implement and put your version checking logic in it i.e. a function that returns the major, minor and build number the plugin is compatible with that you call after initializing the plugin.

Depending on how strict you want to check your versions you can then respond in the application. (I also recommend you use SemVer for the versions, you'll see why as your API matures)

This also allows you to check for versions too old or too new to run on your application.

Upvotes: 1

Related Questions