2

В this stackoverflow question Я узнал, что Призма/Единство не такое развязанное, как я думал, например. если у меня есть этот класс, который получает menuManager, введенный в его конструктор, тогда я должен убедиться, что, что этот класс фактически существует где-то (я думал, что вы можете просто вытащить .dll, содержащую класс, и контейнер будет иметь дело с это, например, впрыскивание нуля в своем месте):Как я могу свободно ссылаться на модули в Призме, чтобы они могли или не могут существовать?

public class EmployeesPresenter 
{ 
    public EmployeesPresenter(IMenuManager menuManager) 
    { 

    } 
} 

но я могу с этим справиться: приложение не может работать без MenuModule (или же, как это было предложено, я мог бы иметь NullMenuModule, которая не делает ничего, но сохраняет приложение от взлома).

Однако приложение, которое я создаю, будет иметь класс MenuManager в MenuModule, и каждый модуль должен будет зарегистрировать все, что он хочет иметь в меню с помощью MenuManager. Тем не менее, я хочу, чтобы можно было заменить меню Menu 0 модели, например. есть InfragisticsMenuModule и имеют TelerikMenuModule и т.д.

Однако, когда я нахожусь в, например, CustomerModule, чтобы использовать TelerikMenuModule, Мне нужно ссылаться на него. И когда я хочу использовать InfragisticsMenuModule, мне нужно это сделать.

Итак, как я смогу «горячей замены» TelerikMenuModule с InfragisticsMenuModule без перекомпиляции всех моих модулей с новыми ссылками, например. Я хочу, чтобы заменить это:

Application.exe 
Customers.dll 
TelerikMenuModule.dll 

с этим:

Application.exe 
Customers.dll 
InfragisticsMenuModule.dll 

и просто иметь возможность перезапустить приложение и работает с новым InfragisticsMenuModule.dll и не жалуется, что TelerikMenuModule.dll нет дольше существует.

ответ

5

Это где интерфейсы приходят Вам нужно что-то вроде:.

public interface IMenuSystem 
{ 
    // whatever operations need to be offered by a menu system 
} 

Application.exe и Customers.dll может относиться только к этому интерфейсу. Они не позволяют узнать о конкретной реализации.

Затем вы должны использовать шаги настройки (вызывая методы Register... или используя файл конфигурации), чтобы указать, какой тип обеспечит реализацию MenuSystem.

+0

@Earwicker: но как бы реализовать это, например. как мне «вызвать регистр», я нашел в документации Unity раздел «Как заполнить каталог модулей из файла конфигурации или каталога в WPF», с которым я буду работать. –

+0

Да, это звучит как правильная вещь. –

+2

Это правильная техника. В своей оболочке вы регистрируете объект с вашим контейнером, который реализует IMenuSystem. Модули «Клиент» просто заявляют, что им нужна IMenuSystem, и ваша оболочка будет внедрять реализацию, которая знает об Infragistics или знает о Telerik. Вам нужно только, чтобы каждый модуль ссылался на DLL «Контракты», который просто содержит определения вашего интерфейса. Это 100% правильный ответ. Мы делаем это в нашем собственном проекте, и он отлично работает. –

2

По понятным причинам MEF приходит на ум здесь и предназначен для таких вещей. У меня не было возможности использовать Unity, поэтому я не уверен, что у него есть что-то построенное (например, сканирование каталога для реализации IMenuModule), но MEF может это сделать.

Предложение также заключается в том, чтобы установить этот IMenuModule в общую сборку (отдельно от другой сборки). Обычно я называю эту вещь Something.Core.dll.

У вас могут быть: Application.exe, Customer.dll, Application.Core.dll и конкретная реализация MenuModule.

Ваша конкретная реализация MenuModule будет ссылаться на сборку Application.Core, чтобы получить доступ к ее интерфейсу IMenuModule и реализовать ее там.

+0

, так что вы говорите: (1) сделайте Application.Core.dll с IMenuModule, (2) сделайте InfragisticsMenuModule с «MenuModule: IMenuModule» и жесткой ссылкой Application.Core.dll и (3) в Customers.dll сделать твердую ссылку на Application.Core.dll? Любая причина, почему у вас есть Application.Core вообще, а не просто разместить все свои интерфейсы в приложении? –

+0

Это просто из привычки :). Вы можете поместить его в приложение, если хотите. –

+0

, который хорошо работает, пока я не зарегистрирую свой объект: container.RegisterType (новый ContainerControlledLifetimeManager()); тогда мне нужно иметь твердую ссылку на модуль InfragisticsModule. –