MEF Зависимости и управление версиями - PullRequest
11 голосов
/ 11 февраля 2011

У меня есть система, которая использует MEF для загрузки деталей.Каждая из этих частей основана на базовой библиотеке.Когда я собираю проект, я добавляю номер версии в файлы .dll следующим образом:

  • part1-1.0.0.0.dll
  • part2-1.0.0.0.dll

Также есть приложение, которое выполняет MEF-композицию.Он также использует библиотеку ядра.Я обнаружил, что могу просто развернуть dll-файлы «part», и композиция работает нормально, потому что приложение уже загрузило базовую библиотеку, на которую опираются части.Моя файловая система выглядит примерно так:

  • / 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 голосов
/ 11 февраля 2011

Разве строгие имена не позаботятся о вашей проблеме? Если сборка строится на основе строго именованной зависимости, то вы знаете, что она будет принимать только ту же самую зависимость вплоть до последнего байта.

В качестве альтернативы, если строгие имена слишком ограничены, вы можете указать номера версий в именах типов. Например:

[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;
    }
}
1 голос
/ 01 апреля 2011

Вам нужно дать вашей сборке ядра все ваши детали строгие имена , тогда они будут требовать точного соответствия при загрузке ссылочных сборок.Это также означает, что вам потребуется развернуть несколько копий сборки ядра.Т.е. вместо

  • / parts / part1-v1.dll
  • / parts / part1-v2.dll
  • / parts / part2-v1.dll
  • composer-v1.exe
  • core-v1.dll
  • core-v2.dll

У вас будет:

  • / 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

Способ IВ прошлом мы просто хранили каждую деталь в отдельной папке вместе со всеми нужными ей зависимостями.Даже если они (в настоящее время) имеют ту же версию, что и в приложении.Так что, когда ваше приложение перейдет на core-v2, все части, которые полагались на core-v1, все равно будут иметь его.

...