MEF依赖项和版本控制

11
我有一个使用MEF加载部件的系统,这些部件都依赖于核心库。在构建项目时,我会向.dll文件添加版本号,例如:
  • part1-1.0.0.0.dll
  • part2-1.0.0.0.dll
此外,有一个应用程序执行MEF组合,它也使用核心库。我发现我只需部署“部分”dll,组合就可以正常工作,因为应用程序已经加载了部分所依赖的核心库。所以我的文件系统看起来像这样:
  • /parts/part1-v1.dll
  • /parts/part2-v1.dll
  • composer-v1.exe
  • core-v1.exe
我遇到的问题是如何处理核心和部分的版本。假设我更新了核心和其中一个部分。然后,我部署了这些更改。现在,我的文件系统可能如下所示:
  • /parts/part1-v1.dll
  • /parts/part1-v2.dll
  • /parts/part2-v1.dll
  • composer-v1.exe
  • core-v1.dll
  • core-v2.dll
如何确保part1-v1.dll使用core-v1.dll,而part1-v2.dll使用core-v2.dll?我需要加载所有版本的部件并使用适当版本的核心。
[Export(typeof(IPart))]
public class Part1
{
    public string GetSomethingFromCore()
    {
        return Core.GetSomethingFromCore();
    }
}

[Export(typeof(IPart))]
public class Part2
{
    public string GetSomethingFromCore()
    {
        return Core.GetSomethingFromCore();
    }
}
2个回答

5

您是否考虑过使用 强命名 解决您的问题?如果程序集是针对一个强命名依赖项构建的,那么您就知道它只会接受完全相同的依赖项,直到最后一个字节。

或者,如果强命名太过严格,您可以在类型名称中添加版本号。例如:

[Export(typeof(IPart))]
public class Part1v1
{
    private readonly ICorev1 core;

    [ImportingConstructor]
    public Part1v1(ICorev1 core)
    {
        this.core = core;
    }
}

[Export(typeof(IPart))]
public class Part1v2
{
    private readonly ICorev2 core;

    [ImportingConstructor]
    public Part1v2(ICorev2 core)
    {
        this.core = core;
    }
}

3
我支持这种方法。注意Wim已经将“Core”功能抽象成接口,这很重要,因为在Lance给出的例子中,他似乎静态地引用了“Core”,而Part1和Part2实际上会引用不同的静态单例对象,这通常不是预期的行为。通过将功能抽象成接口,“core”参数实际上可以是单例_实例_,即相同的对象,通过两个不同版本的接口(ICorev1和ICorev2)发布功能。 - Adam
看一下所有的Microsoft Office互操作程序集,注意它们有v8、v9、v10等dll(命名空间中带有版本号)。每个新版本不会重新定义上一个版本的功能,而只是在其基础上添加。因此,从维护的角度来看,您的“核心”实现将(随着时间的推移)看起来像这样(伪代码):内部类Core:ICorev1、ICorev2 { ICorev1.GetSomethingFromCore() {} ICorev2.GetSomethingFromCore2() {} } - Adam

1

您需要给您的核心程序集所有部件强名称, 然后在加载引用的程序集时,它们将需要精确匹配。这也意味着您需要部署多个核心程序集的副本。例如:

  • /parts/1-1/part1-v1.dll
  • /parts/1-1/core-v1.dll
  • /parts/1-2/part1-v2.dll
  • /parts/1-2/core-v2.dll
  • /parts/2-1/part2-v1.dll
  • /parts/2-1/core-v1.dll
  • composer-v1.exe
  • core-v1.dll
  • core-v2.dll
我过去的做法是,将每个部分与其所需的所有依赖项一起存储在单独的文件夹中。即使它们(当前)与应用程序中的版本相同。这样,当您的应用程序转移到core-v2时,所有依赖于core-v1的部分仍将拥有它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接