MEF and Versioning

I am considering using MEF to solve the problem of managing plugins. In the block, he says “there are no hard dependencies,” but, as far as I can see, the dependency is hard on the import / export interface.

My concern is this. My extensible application is written by me. Plugins are written by third parties. So let's say we all start with V1. My application defines the interface IPluginthat the plugin components need to implement. We deploy the application, and users install a bunch of third-party plugins. All is well and good.

Now I am updating my application and I want to add a new method to the plugin interface. As I can see, I have 2 options:

  • Edit the interface - perhaps badly, and this will violate the existing plugins, because they will no longer correctly implement the interface.
  • Create a new "V2" interface that inherits from the original

    open interface IPluginV2: IPlugin {}

Now I have a problem. My users have a bunch of third-party plugins that implement IPlugin, but now I require them to implement IPluginV2. I assume that these third-party plugins will no longer work until developers implement the new interface.

Does MEF have a way to deal with this situation? I am really looking for a way that allows me to develop my application when old plugins continue to work without rebuilding. What is the best way to handle this?

+5
source share
2

, , , . , System.AddIn , MEF.

, V1 :

public interface IPlugin
{
    string Name { get; }
    string Publisher { get; }
    string Version { get; }

    void Init();
}

V1 . Contracts.v1.

V1:

[Export(typeof(IPlugin))]
public class SomePlugin : IPlugin
{
    public string Name { get { return "Some Plugin"; } }

    public string Publisher { get { return "Publisher A"; } }

    public string Version { get { return "1.0.0.0"; } }

    public void Init() { }

    public override string ToString()
    {
        return string.Format("{0} v.{1} from {2}", Name, Version, Publisher);
    }
}

IPlugin. Plugin.v1 "" .

, V1:

class Host : IDisposable
{
    CompositionContainer _container;

    [ImportMany(typeof(IPlugin))]
    public IEnumerable<IPlugin> Plugins { get; private set; }

    public Host()
    {
        var catalog = new DirectoryCatalog("plugins");
        _container = new CompositionContainer(catalog);
        _container.ComposeParts(this);
    }

    public void Dispose() { _container.Dispose(); }
}

IPlugin , "".

V2, , :

public interface IPluginV2
{
    string Name { get; }
    string Publisher { get; }
    string Version { get; }
    string Description { get; }

    void Init(IHost host);
}

. , :

public interface IHost
{
    //Here we can add something useful for a plugin.
}

Contracts.v2.

, V1 V2:

class V1toV2PluginAdapter : IPluginV2
{
    IPlugin _plugin;

    public string Name { get { return _plugin.Name; } }

    public string Publisher { get { return _plugin.Publisher; } }

    public string Version { get { return _plugin.Version; } }

    public string Description { get { return "No description"; } }

    public V1toV2PluginAdapter(IPlugin plugin)
    {
        if (plugin == null) throw new ArgumentNullException("plugin");
        _plugin = plugin;
    }

    public void Init(IHost host) { plugin.Init(); }

    public override string ToString() { return _plugin.ToString(); }
}

IPlugin IPluginV2. , Init , Init V1.

, , V2:

class HostV2WithVersioning : IHost, IDisposable
{
    CompositionContainer _container;

    [ImportMany(typeof(IPluginV2))]
    IEnumerable<IPluginV2> _pluginsV2;

    [ImportMany(typeof(IPlugin))]
    IEnumerable<IPlugin> _pluginsV1;

    public IEnumerable<IPluginV2> Plugins
    {
        get
        {
            return _pluginsV1.Select(p1 => new V1toV2PluginAdapter(p1)).Concat(_pluginsV2);
        }
    }

    public HostV2WithVersioning()
    {
        var catalog = new DirectoryCatalog("plugins");
        _container = new CompositionContainer(catalog);
        _container.ComposeParts(this);
    }

    public void Dispose() { _container.Dispose(); }
}

IPlugin IPluginV2, IPlugin IPluginV2 . V2.

, V2 V1.

autofac IoC, MEF .

+11

( ), :

  • MEF AggregateCatalog . , V1 V2

  • MEF, DLL , , ,

?

Cheers, dimamura

+1

All Articles