2015-03-17 1 views
1

Использование принципов инъекции зависимостей и контейнера DI, каков правильный шаблон для запуска дочернего диалога, для которого требуется выбор, сделанный в родительском окне как зависимость? Пример. Выберите PersonViewModel в списке в главном окне и нажмите кнопку, чтобы открыть окно «Сведения». Окно Details должно передать PersonViewModel для предоставления DataContext.Каков правильный шаблон для создания экземпляра и отображения окна, которое зависит от значения, выбранного в текущем окне?

два метода, которые я нашел:

  1. Пасс в дочернем окне, как зависимость и использовать инъекции собственности, чтобы обеспечить зависимость дочернего окна перед вызовом ShowDialog.
  2. Пройдите в ViewFactory, который используется для разрешения дочернего окна и использует инъекцию свойств, чтобы обеспечить зависимость дочернего окна до вызова ShowDialog.

То, что я ищу, является общепринятым проверяемым образцом. Все примеры DI, которые я нахожу, кажутся всего лишь одним слоем, или не требуют зависимости, выбранной в родительском окне.

Спасибо!

+0

Вы работаете в WPF? – Marwijn

+0

Да. К сожалению, я отметил этот WPF, но забыл упомянуть в описании. –

ответ

1

Я предлагаю другой метод. Способ, которым я рекомендовал бы это сделать, - создать небольшой объект-менеджер для отображения диалогового окна, через который вы можете передать параметры в модель представления диалогового окна, прежде чем использовать его для создания самого окна.

Создание фабрики для вашего окна и вид-модели и использовать их что-то вроде этого:

public class DetailsWindowDisplayer : IDetailsWindowDisplayer 
{ 
    private readonly IDetailsWindowFactory windowFactory; 
    private readonly IDetailsWindowViewModelFactory viewModelFactory; 

    public DetailsWindowDisplayer(
     IDetailsWindowFactory windowFactory, 
     IDetailsWindowViewModelFactory viewModelFactory) 
    { 
     this.windowFactory = windowFactory; 
     this.viewModelFactory = viewModelFactory; 
    } 

    public void ShowDetails(IPersonViewModel personViewModel) 
    { 
     var windowViewModel = this.viewModelFactory.Create(personViewModel); 
     var window = this.windowFactory.Create(windowViewModel); 
     window.Show(); 
    } 
} 

Тогда это простой случай инъекционного IDetailsWindowDisplayer в родительское представление-модели, а также вызов метода ShowDetails. Это абстрагирует показ диалога на один вызов, а DetailsWindowDisplayer несет только одну ответственность.

Чтобы сделать его полностью проверяемым, ваша фабрика окон должна вернуть интерфейс. Вы можете сделать это с помощью следующей иерархии:

public interface IDialogWindow 
{ 
    void Show(); 
} 

public interface IDetailsWindow : IDialogWindow 
{ 
} 

public class DetailsWindow : Window, IDetailsWindow 
{ 
    // The Show() method from IDialogWindow is automatically implemented 
    // by the WPF Window class 
} 

Если вы предпочитаете держать окно детали как синглтон, вы можете впрыснуть окно в конструктор DetailsWindowDisplayer и либо 1. установить новый вид-модель на нем каждый раз, когда это показано, или 2. сделайте свою модель-образец одним синглом, поместите в окно свойство ViewModel и свойство Person на модель представления, а затем установите Person как новый экземпляр PersonViewModel каждый раз.

0

В целом я стараюсь не использовать контейнер для разрешения Представлений. Существует несколько проектов, которые специально предназначены для создания привязок View-ViewModel.

Я предлагаю вам проверить на Caliburn.Micro, для материала пользовательского интерфейса и использовать контейнер для всех инъекций зависимостей. Если вам нужна помощь в настройке Caliburn.Micro с Windsor, пожалуйста, дайте мне знать.