Этот вопрос все о дизайне и Simple Injector является лишь деталью реализации где-то в composition root.
Я написал еще answer здесь, на stackoverflow, на аналогичный вопрос, касающийся Windows Forms. Идеи в этом ответе не отличаются друг от друга для WPF.
Есть несколько возможностей сделать это в зависимости: - Сколько, кроме главного окна, окна необходимы - Есть ли другие окна также должны перемещаться в другие окна или другие окна открываются только от главного window - Каков стиль жизни окон. Это, как правило, довольно трудно создать окна, которые действительно синглтон для полного жизненного цикла приложения
- Если приложение состоит только из нескольких окон, и окно может иметь одноплодной образ жизни, просто поставить необходимые окна в конструктор главного окна. Если образ жизни не может быть одноточечным, вы можете ввести фабричный метод
Func<T>
для каждого окна.
- Сделайте первую или основную часть окна корня композиции. Поместите контейнер в качестве параметра конструктора и разрешите другие окна непосредственно из контейнера, прежде чем показывать их. В этом случае единственной и единственной ответственностью этого окна должно быть открытие/показ окон приложения.
- Создайте
INavigationService
с реализацией также часть корня композиции
- Используйте инструмент MVVM как Caliburn Micro и перенаправлять метод
GetInstance()
в классе Caliburn Загрузчик непосредственно к простой Injector контейнер
- сделать полное изменение дизайна .. .
Возможности 1, 2 и 4 просты в применении. NavigationService
в самом простой форме, также довольно прост и будет выглядеть примерно так:
public class NavigationService : INavigationService
{
private readonly Container container;
public NavigationService(Container container)
{
this.container = container;
}
public void ShowView<TView>() where TView : Window
{
var view = this.CreateWindow<TView>();
view.Show();
}
public bool? ShowDialog<TView>() where TView : Window
{
var view = this.CreateWindow<TView>();
return view.ShowDialog();
}
private Window CreateWindow<TView>() where TView : Window
{
return this.container.GetInstance<TView>();
}
}
Если бы, однако, взять другой угол зрения на это, мы могли бы создать дизайн, который, по сути версии пользовательского интерфейса этой конструкции для обработки commands и queries. Эти шаблоны действительно помогут решить ваши проблемы, как на стороне бизнес-пользователей, так и на стороне пользователя.
В большинстве приложений LOB экран обычно открывается, чтобы сделать выбор или выбор, а другая часть - экранами, позволяющими пользователю вводить данные и сохранять их в некотором хранилище данных. Если мы рассмотрим эту проблему с абстрактного уровня, не имеет значения, что это обрабатывается частью пользовательского интерфейса, чтобы пользователь мог взаимодействовать. Мы могли бы просто подумать об этом как о службе, которая запрашивает или редактирует данные из определенной службы. Это может быть веб-сервис, но также и непосредственно пользователь.
Определяя некоторые простые интерфейсы, а также использовать шаблон проектирования MVVM мы можем создать реализацию ViewModel, которые делают именно это:
public interface IEditViewModel<TEntity>
{
EditResult EditEntity(TEntity entityToEdit, DialogHandler dialogHandler);
}
public interface IChooseViewModel<TEntity>
{
TEntity ChooseEntity(DialogHandler dialogHandler);
}
public class ChooseEntityService
{
private readonly Container container;
private readonly DialogHandler dialogHandler;
public ChooseEntityService(Container container, DialogHandler dialogHandler)
{
this.container = container;
this.dialogHandler = dialogHandler;
}
public TEntity ChooseEntity<TEntity>()
{
var viewModel = this.container.GetInstance<IChooseViewModel<TEntity>>();
return viewModel.ChooseEntity(this.dialogHandler);
}
}
В окне нуждающегося выбрать клиента мы вводим ChooseService
. Эта служба найдет правильную реализацию, и DialogHandler
будет реализацией, которая показывает представление через ваш любимый инструмент MVVM.
This answer подробнее об этом дизайне.