如何在MEF中支持接口的双版本



我正在管理一个通过共享合同共享组件的复杂项目。有几个主机和许多这样的共享插件。

为了简化兼容性和部署,我们将同意两组接口:v(latest)和v(latest-1)。无论如何,每个主机必须同时支持这两个集合。

理想情况下,我希望编写主机只针对最新的v(最新),并通过v(最新)合同开发人员负责的一些自定义适配器代码透明地适应旧组件。

Host importing v(Latest) -> Adapter -> Plugin export v(Latest-1)

有什么方法可以在MEF中实现这一点吗?我还不太熟悉它的可扩展性模型,我以前从未使用过它。

不要做所有插件的ImportMany,你可以导入一个IPluginProvider。然后,您可以将必要的适配器逻辑放入插件提供程序实现中。例如:

[Export(typeof(IPluginProvider))]
public PluginProvider : IPluginProvider
{
   [ImportMany]
   public IEnumerable<IPlugin2> Plugins { get; set; }
   [ImportMany]
   public IEnumerable<IPlugin1> LegacyPlugins { get; set; }
   public IEnumerable<IPlugin2> GetPlugins()
   {
      var adaptedPlugins = this.LegacyPlugins.Select(x => new Adapter(x));
      return this.Plugins.Concat(adaptedPlugins);
   }
}

此选项仅在您控制插件消费者时有效,以便您可以更改它们以导入IPluginProvider。如果没有,您需要使用ExportProvider实现来设置MEF容器,该实现在某种程度上可以识别适配器。

MEF没有提供这样的东西,所以我推出了自己的实验性ExportManyProvider。它允许您使用ExportMany属性导出像上面那样的适配器服务。有关如何使用它的示例,请参阅测试代码。

最新更新