#silverlight #ioc-container #viewmodel #mvvm-light #viewmodellocator
#silverlight #ioc-контейнер #viewmodel #mvvm-light #viewmodellocator
Вопрос:
Как вы реализуете шаблон ViewModelLocator при использовании дочерних контейнеров IOC? Типичная реализация локатора выглядит примерно так:
public IViewModel ViewModel
{
get { return Services.ServiceLocator.GetInstance<IViewModel>(); }
}
где сервисы.ServiceLocator — это статическое свойство, доступное только для чтения. Но это не работает, если вы используете дочерние контейнеры. Вот мое определение сервисов.ServiceLocator с использованием дочерних контейнеров:
public static IServiceLocator ServiceLocator
{
get { return RootContext.ServiceLocator; }
}
Очевидно, что это неверно: мои введенные зависимости будут поступать из корневого контейнера вместо дочернего контейнера. (Дочерний контейнер создается и загружается с помощью чего-то другого, кроме моего текущего представления. Таким образом, мой текущий вид может автоматически подключаться из дочернего контейнера.)
Итак, как вы получаете правильный контейнер в сценарии с несколькими контейнерами? Стандартный ответ заключается в том, чтобы внедрить его в конструктор, но это кажется невозможным с ViewModelLocator: для этого требуется конструктор по умолчанию, чтобы его можно было сконструировать из XAML.
Мне также нужно решение, которое работает как в Silverlight 4, так и в WPF 4.0, поскольку я работаю над составным приложением PRISM (таким образом, без расширений разметки). Так получилось, что я использую Unity в качестве контейнера IOC. О, и решение должно работать в Blend (то есть оно не должно препятствовать созданию новой модели представления во время разработки, которая обходит контейнер IoC).
Ответ №1:
Обычно дочерний контейнер определяет иерархию поиска. Однако вашему базовому контейнеру придется создать свой дочерний контейнер, передав себя в качестве параметра.
Для доступа к дочернему контейнеру у вас может быть свойство, которое возвращает дочерний контейнер — либо одноэлементный экземпляр, либо временный (т. Е. новый) экземпляр. Однако, если вы хотите совместимый доступ, вам следует учитывать, что дочерний контейнер должен находиться в ваших ресурсах, чтобы привязываться к нему во время разработки.
В любом случае вы должны убедиться, что экземпляры ваших ViewModels должным образом очищены, чтобы не возникло утечек памяти.
Редактировать: В вашем конкретном случае это может быть полезно. Хотя у меня не было времени посмотреть видео, Лоран сказал мне, что он демонстрирует способ динамической загрузки модели представления. Я надеюсь, что это действительно поможет вам!
Комментарии:
1. Я немного прояснил первоначальный вопрос. Часть, на которой я застрял, заключается в следующем: если я нахожусь на n уровнях в глубине дочерних контейнеров, как я могу получить n-й контейнер, чтобы выполнить автоматическую проводку в view model locator? n определяется во время выполнения и зависит от вида: второй вид может иметь глубину m уровней, а третий вид может иметь глубину x уровней. Таким образом, определение статических шлюзов для каждого уровня непрактично (не говоря уже о том, что у вас может быть несколько дочерних элементов на каждом уровне, так как бы вы разрешили правильный контейнер на этом уровне).
2. Пока дочерние контейнеры IoC и VML выглядят как несовместимые шаблоны. Я бы так хотел, чтобы мне доказали, что я ошибался.