Сконфигурируйте и предоставьте синглтон всем модулям в приложении MEF / PRISM - PullRequest
2 голосов
/ 03 августа 2010

У меня есть приложение (просто тест), которое использует MEF и PRISM.

Довольно просто загрузить некоторые экспорты, которые соответствуют определенным интерфейсам и передать их конструктору загружаемых модулей, но я пытаюсь сделать что-то другое.

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

Я не хочу иметь публичное свойство в Shell или какой-нибудь вспомогательный класс, который предоставляет этот случай, как это, вероятно, будет считаться плохой практикой ... и мне не очень нравится.

Обновление: перефразируя вопрос ниже

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

Мне удалось загрузить их в модуль в приложении призмы, например, так:

[ImportingConstructorAttribute()]
public HelloWorldView(IDataTransportService dataTransportService,
                      IMessageFactory messageFactory,
                      IDataFactory dataFactory,
                      IDataProcessor dataProcessor,
                      IDataCollector dataCollector)
{
        var client = new ControllerClient(dataTransportService,
                                          messageFactory,
                                          dataProcessor
                                          dataCollector);
}

В этом случае модуль создает действительный экземпляр класса ControllerClient.

Но вместо того, чтобы передавать эти интерфейсы конструктору, я хочу иметь модуль конструктор, как это:

[ImportingConstructorAttribute()]
public HelloWorldView(IClient client)
{
   this.client = client;
}

Конструктор для реализации IClient (ControllerClient) имеет [ImportingConstructorAttribute ()], поэтому я ожидал, что зависимости будут введены автоматически в этот момент ... однако, используя этот код, конструктор даже не достигается.

Мне нужно иметь один экземпляр интерфейса IClient, который используется ВСЕ модули в приложении. (Теперь я понимаю, что Shared является значением по умолчанию для импорта MEF).

Какой лучший способ сделать это? Почему я не могу иметь конструктор модуля, принимающий IClient, а что если я захочу представить экземпляр класса таким образом, если он не знает о mef?

Итак, где в приложении mef / prism вы бы определили этот экземпляр, который может использоваться всеми модулями? И это то, что часто называют Услугой (но я мог только найти руководство по предоставлению услуг единству / призме).

Надеюсь, на этот раз я лучше объяснил свою проблему.

Обновление 2: Поскольку для импорта MEF используется значение по умолчанию, я могу импортировать реализацию IClient в каждый модуль, но затем мне нужно выяснить, почему не вставляются зависимости

1 Ответ

2 голосов
/ 03 августа 2010

Для MEF Shared является значением по умолчанию, поэтому каждый импорт интерфейса разрешается в один и тот же экземпляр. Конфигурация этого экземпляра может происходить в конструкторе класса, или вы можете реализовать IPartImportsSatisfiedNotification в своем классе обслуживания 'singleton', который перезвонит, когда MEF завершит разрешение импорта вашего класса.


Читая ваше обновленное описание, кажется, что вы не можете настроить класс в его конструкторе или после того, как его импорт разрешен, так как вам нужна дополнительная контекстная информация. Если это так, то вы можете настроить класс вручную в командной консоли и вручную добавить экспорт после того, как он был создан с помощью метода ComposeParts контейнера. Это сделает ваш «сконфигурированный» экземпляр тем, который будет использоваться для разрешения любых тегов [Export], которые вы применили к классу. Конечно, вам придется сделать это до того, как вы создадите в контейнере что-то еще, что будет зависеть от экземпляра.

...