Поиск экспортов для объектов, созданных после вызова ComposeParts - PullRequest
4 голосов
/ 25 апреля 2011

У меня очень простое приложение с одним экспортом и несколькими импортом для одного типа.

После вызова ComposeParts я вижу, что импорт работал в том же классе, откуда я вызывал ComposeParts, - свойство MyService подключено.

Проблема в том, что у меня есть другой UserControl, которому нужен доступ к MyService, и свойство не установлено - оно находится в том же пакете и т. Д., Но оно не установлено в момент вызова ComposeParts.

Если я сделаю свой CompositionContainer общедоступным / статическим и вызову ComposeParts и передам UserControl, свойство MyService установлено, но это ужасное решение.

Может кто-нибудь пролить свет на то, что происходит? Является ли ComposeParts достаточно умным, чтобы подключить существующие объекты, или атрибут Import сможет работать с объектами позднее? Я что-то неправильно подключил?

public partial class App : Application    
{

  protected override void OnActivated(EventArgs e)
  {
    AssemblyCatalog assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
    compositionContainer = new CompositionContainer(assemblyCatalog);
    compositionContainer.ComposeParts(this);
  }

  [Import(typeof(MyService))]
  public MyService MyService { get; set; }
}

Обновление:

Я пытаюсь обновить проект C # на 250 000 строк из модели поставщика услуг, найденной в .Net 2.0, до MEF.

Не похоже, что вы можете автоматически подключать новый экземпляр объекта к нужным службам только через атрибут Import. Кажется, вам нужно повторно запустить ComposeParts или что-то в этом роде. Lame.

В модели провайдера / контейнера .Net 2.0 вам нужно было явно добавить дочерние объекты в родительские контейнеры, и поиск службы был бы рекурсивной проверкой от дочерних к родительским контейнерам. Я не уверен, что Corrolary в MEF ??

Ответы [ 2 ]

1 голос
/ 19 мая 2011

Одна вещь, которая выглядит как проблема, состоит в том, что у вас есть только одна сборка в вашем каталоге (исполняющая сборка). Если это проект с одной сборкой, в котором все элементы [Export] находятся в одной сборке, он будет работать нормально. Если нет, то вам нужно будет передать все сборки в каталог или использовать DirectoryCatalog.

Вы можете пометить UserControl классы [Export], затем вместо вызова их конструкторов вы можете использовать CompositionContainer.GetExportedValue(), чтобы создать UserControl и выполнить все его [Import] потребности за один раз. Тем не менее, это не всегда возможно с пользовательским интерфейсом, если формы уже имеют элементы управления во время разработки. В этом случае вам нужно вызвать ComposeParts для установки значений [Import].

Это действительно сводится к тому, как вы настраиваете классы UserControl в приложении. Если вы подключите его во время выполнения, у вас будет возможность подключиться к CompositionContainer, чтобы создать для вас экземпляры и автоматически подключить их. Если для настройки элементов управления вы используете код времени разработки, вам нужно заменить все ваши GetService() вызовы ComposeParts() вызовами.

0 голосов
/ 31 июля 2012

Вы можете проверить dI.Hook рамки на Codeplex для динамических перехватов

Ссылка: http://dihook.codeplex.com/

...