Мне не совсем понятно, как я могу проектировать, поэтому я сохраняю ссылку на DI-контейнер в корне композиции для приложения Silverlight + MVVM.
У меня есть следующий простой сценарий использования: есть основной вид (возможно, список элементов) и действие, чтобы открыть представление редактирования для одного элемента. Поэтому основной вид должен создавать и показывать вид редактирования, когда пользователь предпринимает действие (например, нажимает на какую-то кнопку).
Для этого у меня есть следующий код:
public interface IView
{
IViewModel ViewModel {get; set;}
}
Затем для каждого представления, которое мне нужно для создания, у меня есть абстрактный factory, например
public interface ISomeViewFactory
{
IView CreateView();
}
Этот factory затем объявляется зависимостью модели родительского представления, например:
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 = ????
}
}
"????" part - моя проблема, потому что модель представления для представления должна быть разрешена из DI-контейнера, чтобы он вносил свои зависимости. Я не знаю, как это сделать, не имея зависимости от DI-контейнера в любом месте, кроме корня композиции.
Одним из возможных решений могло бы быть либо зависимость от модели представления, которая вводится в factory, например:
public class SomeViewFactory : ISomeViewFactory
{
public SomeViewFactory(ISomeViewModel viewModel)
{
// store it
}
public IView CreateView()
{
IView view = new SomeView();
view.ViewModel = viewModel;
}
}
В то время как это работает, проблема состоит в том, что поскольку весь объектный граф подключен "статически" (т.е. модель "родительского" представления получит экземпляр SomeViewFactory, который получит экземпляр SomeViewModel, и они будут жить пока существует модель представления "родительский" ), реализация модели с внедренным представлением является работоспособной, и если пользователь дважды открывает дочерний вид, во второй раз модель представления будет одним и тем же экземпляром и имеет состояние из ранее. Думаю, я мог бы обойти это с помощью метода "Инициализация" или чего-то подобного, но он не совсем пахнет.
Другое решение может заключаться в том, чтобы обернуть DI-контейнер и зависеть от фабрики от оболочки, но он все равно будет "скрывать" DI-контейнер:)
ps: мое текущее решение состоит в том, что фабрики знают о DI-контейнере, и это только они и корень композиции, которые имеют эту зависимость.