Разрыв цепочки импорта .NET MEF - PullRequest
2 голосов
/ 02 сентября 2011

В этом примере вы можете предположить, что toplevel импортирует ClassA. MEF, кажется, прекрасно работает, пока вы импортируете все (например, ClassX). Часто вам не нужно импортировать, потому что classB находится в том же пространстве имен / файла. В результате цепочка импорта теперь разорвана, а импорт myLog никогда не создается. В моем примере ClassB пытается импортировать Logger Service, что может потребоваться почти всем классам.

Что, если есть, является лучшим / лучшим решением MEF для этой проблемы?

1) После разрыва цепочки импорта никогда не используйте импорт снова. Вместо этого вы должны начать создавать / передавать все типы в конструктор (т.е. новый ClassB (myLog)). Это работает в этом примере, но это грязно, если в цепочке есть промежуточные классы, не использующие аргумент.

2) Используйте IServiceLocator в пространстве имен System для импорта ClassB. Насколько я знаю, ServiceLocator (например, Prism Framework) существует только для абстрагирования схемы внедрения зависимостей. В этом примере, если ClassB может импортировать IServiceLocator, он мог бы импортировать ILogger.

3) Вернемся к вызову верхнего уровня ComposeParts (ClassB). Чтобы предотвратить зависание верхнего уровня от ClassB, я мог бы заставить ClassB реализовать интерфейс (IComposeMe), который импортирует верхний уровень. Тогда верхний уровень будет ComposeParts на контейнере для всех импортов IComposeMe. Я не верю, что это предполагаемое решение, потому что оно не описано и не используется в документации инфраструктуры MEF.

4) На самом деле у меня нет идей, пожалуйста, помогите ...

class ClassA {

  // Imports within ClassX will get composed
  [Import]
  ClassX myClassX;

  // Imports within ClassB will NOT be composed!
  var myClassB = new ClassB
}

class ClassB {

  // Fails because ClassB is never Composed
  [Import]
  ILogger myLog;

  myLog.Display("Hello World");
}

[Export]
class ClassX {

  // Works - Imports are satified when ClassX imported
  [Import]
  ILogger myLog;

  myLog.Display("Hello World");
}

Ответы [ 2 ]

1 голос
/ 02 сентября 2011

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

Конечно, на практике вам приходится иметь дело с существующим кодом (и другими разработчиками, скептически относящимися к DI), поэтому вы не всегда можете делать внедрение зависимостей "полностью вниз". В этих случаях вы можете выставить контейнер как глобальную переменную и извлечь из нее необходимые зависимости.

Представление контейнера как глобального по сути является шаблоном Service Locator. У него есть недостатков .

0 голосов
/ 02 сентября 2011

Конечно, вы можете где-нибудь зарегистрировать, какие типы вы хотите импортировать / экспортировать, не сканируя всю сборку.Я не знаю, поможет ли это, но вот ссылка, которую я нашел после того, как немного погуглил: http://blogs.microsoft.co.il/blogs/zuker/archive/2010/10/17/mef-runtime-type-catalog-support-multi-registrations-in-runtime.aspx

...