Как я могу изменить часть композиции в MEF после композиции? - PullRequest
4 голосов
/ 13 апреля 2011

Я настроил свое приложение на наличие обнаруживаемой службы безопасности (ISecurityService), которая имеет один метод IPrincipal GetPrincipal(). Разработчики могут сами решить, как получить принципал (через домен, БД и т. Д.). Таким образом, в моем приложении есть части, которые выполняют определенные действия при запуске, определяемые ролями, в которых находится пользователь, для одного примера я импортировал разделы интерфейса следующим образом:

[Import]
public ISecurityService SecurityService {
    get; set;
}
[ImportMany]
public IEnumerable<ISectionPanel> ImportedPanels {
    get; set;
}
public ObservableCollection<ISectionPanel> Panels {
    get; set;
}
public void OnImportsSatisfied() {
    Panels.Clear();
    IPrincipal p = Thread.CurrentPrincipal;
    foreach (ISectionPanel sp in ImportedPanels.Where(sp => sp.RequiredRole == null || p.IsInRole(sp.RequiredRole))) {
        Panels.Add(p);
    }
}

Не сосредотачивайтесь слишком сильно на реализации, позже это изменится на аннотации, однако, важная вещь, которая заставила меня обрезать потроху, заключалась в том, что состав частей происходил ДО НАЧАЛА установленного участника безопасности. Это значит, что теперь у меня ситуация с кошкой и мышью.

Теперь я решил эту проблему с помощью Lazy<T> для импорта, что повлияло на возникновение цепочки, однако, если другой разработчик детали забудет использовать Lazy<T>, это может вызвать цепную загрузку и вызвать сбой приложения.

Что другие использовали для преодоления таких сценариев, как этот?

Раньше у меня было единство, которым я управлял более ручным способом, просто используя RegisterInstance<T>(T t), я сейчас пытаюсь писать приложения, используя "официальный" MEF, так как это идет с платформой, и мне больше не нужно беспокоиться о единство.

В идеале я бы хотел иметь возможность.

  1. Создание деталей вручную при запуске предыдущей композиции
  2. Создайте составной контейнер вручную, добавив мои предварительно созданные детали (например, RegisterInstance<T>(T t) в единстве
  3. Найдите оставшиеся части, используя обычные методы композиции, показанные в документации.

Ответы [ 2 ]

4 голосов
/ 13 апреля 2011

Вы можете инициализировать ваше приложение в два этапа:

public static void Main(string[] args)
{
    using (var container = new CompositionContainer(...))
    {
        // phase 1: compose security service and initialize principal
        var securityService = container.GetExportedValue<ISecurityService>();
        securityService.InitializePrincipal();

        // phase 2: compose the rest of the application and start it
        var form = container.GetExportedvalue<MainForm>();
        Application.Run(form);
    }
}
2 голосов
/ 13 апреля 2011

В MEF то, что более или менее соответствует RegisterInstance, будет методом AddExportedValue. Это будет работать, если хост создал службу безопасности без использования MEF. Поскольку вы все еще хотите открыть службу безопасности с помощью MEF, то, что предлагает Вим, вероятно, является хорошим решением.

...