Пишу код под одну бизнес-платформу на C# .NET 4 и WPF. Основное действие — это открытие окна карточки с данными — окно создает платформа, а GUI внутри окна уже мой. Никакой локатор до сей поры не использовался, все данные ViewModel-и получали через Messenger из MVVM Light.
Ранее каждое новое окно запускалось в изолированном окружении, то есть при открытии каждого нового окна отрабатывали конструкторы ViewModel-ей и в них проходила подписка на сообщения, в том числе и события закрытия карточки-окна.
Вышла новая версия платформы, в которой создатели придумали хитрый оптимизационный ход — теперь при закрытии окна — оно просто скрывается, а объекты, связанные с ним — не попадают под сборку мусора, соответственно, конструкторы всем ViewModel-ей отрабатывают только при первом открытии окна. Таким образом пропала возможность во ViewModel-ях отписываться от сообщение при закрытии карточки, так как тогда при открытии следующей (когда конструкторы не отрабатывают) — ViewModel не получили бы нужные сообщения. Ладно, подумал я — не будем отписываться и продолжил тестировать.
Тут выяснилась главная проблема — пользователь имеет возможность открывать несколько карточек одновременно. Опишу, к чему это приводит:
Пользователь открывает первую карточку. Конструкторы отрабатывают, подписки проходят, карточка работает корректно.
Не закрывая первую, пользователь открывает вторую карточку. Конструкторы отрабатывают, подписки проходят, карточка работает корректно.
Закрываем обе, открываем третью. Конструкторы не отрабатывают, в памяти существуют подписки от первой и от второй карточки, так как обе были закрыты и все члены объектов были обнулены, то отличий никаких. Сообщения проходят и их получают оба набора подписок.
Открываем еще одну карточку, платформа пытается ее встроить во второй набор объектов, но, так как члены второго набора объектов заполнены данными, полученными при открытии первой карточки — вторая карточка разваливается.
Итого, задача получается такая — необходимо контролировать в моменты открытия и закрытия карточек процесс создания ViewModel-ей, дабы была возможность при открытии создавать подписки, а при закрытии снимать их. Как я понимаю — за это и отвечает ViewModelLocator с Dictionary<Token, IViewModel> — для хранения различных экземпляров ViewModel-ей для различных UserControl-ов. Но, опять же, насколько я понимаю, этот Dictionary должен быть объявлен, как static, дабы использоваться в XAML. И, соответственно, в случае нескольких открытых карточек они будут получать один и тот же Dictionary, что конечно же неверно.
Соответственно, вопрос — как можно добиться решения поставленной задачи? Чтобы у разных карточек был разный Dictionary? Или все можно еще проще решить?