Мне не совсем понятно, как я могу проектировать, поэтому я сохраняю ссылку на DI-контейнер в корне композиции для приложения Silverlight + MVVM.
У меня есть следующий простой сценарий использования: есть главное представление (возможно, список элементов) и действие, чтобы открыть представление редактирования для одного отдельного элемента. Таким образом, основной вид должен создавать и отображать вид редактирования, когда пользователь выполняет действие (например, нажимает какую-то кнопку).
Для этого у меня есть следующий код:
public interface IView
{
IViewModel ViewModel {get; set;}
}
Затем для каждого представления, которое мне нужно создать, у меня есть абстрактная фабрика, например,
public interface ISomeViewFactory
{
IView CreateView();
}
Эта фабрика затем объявляется зависимостью от "родительской" модели представления, например так:
public class SomeParentViewModel
{
public SomeParentViewModel(ISomeViewFactory viewFactory)
{
// store it
}
private void OnSomeUserAction()
{
IView view = viewFactory.CreateView();
dialogService.ShowDialog(view);
}
}
Так что пока все хорошо, DI-контейнера не видно :). Теперь идет реализация ISomeViewFactory:
public class SomeViewFactory : ISomeViewFactory
{
public IView CreateView()
{
IView view = new SomeView();
view.ViewModel = ????
}
}
"????" Отчасти это моя проблема, потому что модель представления для представления должна быть разрешена из DI-контейнера, чтобы в него вставлялись его зависимости. Чего я не знаю, так это как я могу это сделать, не имея зависимости от DI-контейнера нигде, кроме корня композиции.
Одним из возможных решений было бы наличие зависимости от модели представления, внедряемой в фабрику, например:
public class SomeViewFactory : ISomeViewFactory
{
public SomeViewFactory(ISomeViewModel viewModel)
{
// store it
}
public IView CreateView()
{
IView view = new SomeView();
view.ViewModel = viewModel;
}
}
Хотя это работает, проблема заключается в том, что, поскольку весь граф объектов подключен «статически» (т. Е. Модель «родительского» представления получит экземпляр SomeViewFactory, который получит экземпляр SomeViewModel, и они будут жить до тех пор, пока существует «родительская» модель представления), реализация модели с внедренным представлением находится в состоянии, и если пользователь дважды открывает дочернее представление, во второй раз модель представления будет того же экземпляра и будет иметь прежнее состояние. Я думаю, я мог бы обойти это с помощью метода «Initialize» или чего-то подобного, но это не совсем пахнет.
Другое решение может заключаться в том, чтобы обернуть DI-контейнер и заставить фабрики зависеть от оболочки, но это все равно будет DI-контейнер "замаскированный" там:)
ps: мое текущее решение состоит в том, что фабрики знают о DI-контейнере, и только они и корень композиции имеют эту зависимость.