2011-02-10 4 views
11

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

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

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

  • /parts/part1-v1.dll
  • /parts/part2-v1.dll
  • композитор-v1.exe
  • ядро-v1.exe

Проблема, с которой я столкнулся, заключается в том, как обращаться с версией ядра и частей. Предположим, что я делаю обновление для ядра и одной из частей. Затем я развертываю изменения. Так что теперь моя файловая система может выглядеть примерно так:

  • /parts/part1-v1.dll
  • /parts/part1-v2.dll
  • /parts/part2-v1.dll
  • композитора -v1.exe
  • ядро-v1.dll
  • ядро-v2.dll

Как я могу убедиться, что part1-v1.dll использует ядро-v1.dll и part1-v2.d ll использует 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(); 
    } 
} 

ответ

5

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

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

[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» до интерфейсов, это особенно важно, потому что в приведенном примере Ланса он, похоже, статически ссылается на «Core», Part1 и Part2 будут фактически ссылаться на разные статические синглтоны, которые обычно не были бы ожидаемое поведение. Исчерпывая функциональность для интерфейсов, аргументы «core» могут фактически быть singleton _instances_, тем же объектом, который публикует функциональность через две разные версии интерфейса (ICorev1 и ICorev2). – Adam

+0

Взгляните на все сборки соединений Microsoft Office и обратите внимание, как они имеют v8, v9, v10 dll и т. Д. (С версией в пространстве имен). Каждая новая версия _does_not_ переопределяет функциональность из последней, но просто _adds_. Таким образом, с точки зрения обслуживания, ваша реализация 'ядро' будет (со временем) выглядеть примерно так (псевдокод): внутренний класс Core: ICorev1, ICorev2 { ICorev1.GetSomethingFromCore() {} ICorev2.GetSomethingFromCore2 () {} } – Adam

1

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

  • /parts/part1-v1.dll
  • /parts/part1-v2.dll
  • /parts/part2-v1.dll
  • композитора-v1.exe
  • сердечника -v1.Dll
  • ядро-v2.dll

Вы будете иметь:

  • /parts/1-1/part1-v1.dll
  • /частей/1-1/ядро-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
  • композитор-v1.exe
  • ядро-v1.dll
  • ядро-v2.dll

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

Смежные вопросы