Должен ли локатор MVVM вызывать какие-либо зарегистрированные функции ViewModel?
Предположим, что есть приложение WPF, которое использует легкий инструментарий MVVM.
Хороший пример этого инструментария - Locator. Замечательно, что он содержит SimpleIoC, который позволяет нам регистрировать сервисы и управлять интерфейсом.
Иногда конструктор Локатора действительно может расти. К сожалению, помимо регистрации интерфейсов, он содержит некоторую логику:
if(SimpleIoc.Default.GetInstance<MainViewModel>().LoadProject())
{
var project = SimpleIoc.Default.GetInstance<MainViewModel>().LoadedProject
SimpleIoc.Default.Register<ConfigService>(new Service(project))
}
Это был только пример - что если мне нужно больше логики во время конструктора локаторов. Может быть, моя Архитектура Сервисов создана неправильно, так как они не являются независимыми, или, может быть, в таких случаях я должен отказаться от использования Locator - но тогда я потеряю DI.
Другое дело, что в нескольких ViewModel есть Ссылка на Locator.GetInstance, которую я нашел другой не очень хорошей практикой, поскольку она должна вводиться через конструктор для обеспечения возможности тестирования.
Другой аспект - это правильное использование с AvalonDock.
AvalonDock - это отличный элемент управления, который позволяет создавать приложения, которые могут быть похожи на такие приложения, как Visual Studio, с закрепляемыми, закрепляемыми панелями.
Эти панели - фактически другие ViewModels, которые связаны с AvalonDock через свойство.
MainViewModel имеет свойство Tools = new Tools[] { ViewModel1, ViewModel2}
Но каждая ViewModel была зарегистрирована в Locator.
поэтому я использую (нарушать СУХОЙ) их в MainViewModel как
Получатель свойства: Locator.GetInstance()
что, на мой взгляд, еще один плохой пример - даже небезопасный. Что делать, если какой-либо сервис, требуемый Avalon Tool ViewModel1, еще не зарегистрирован, но вызывается через getter во время создания экземпляра MainViewModel.
Это начало быть несоответствием. У тебя есть хорошая практика?
Я нашел много примеров, таких как Workspaces (MainViewModel), но в то же время никто не использовал Locator, который я нашел очень полезным.
Я хотел бы сохранить Locator, потому что считаю, что это хорошая вещь, которая позволяет mme сделать мой проект тестируемым благодаря внедрению зависимостей и управляемому интерфейсу.
Любые предложения идей? Я был бы благодарен.
1 ответ
Я бы избежал этого. Как вы правильно заметили, здесь происходит гораздо больше, чем просто регистрация типов.
Вместо этого я бы передал экземпляр ConfigService в Viewmodel в его конструкторе. Пока он зарегистрирован первым, вы можете IOC службы конфигурации и просмотра модели.
SimpleIOC.Register<IViewModel>(()=>{return new ViewModel(SimpleIOC.GetInstance<IConfigService>())});
... Это все из памяти, поэтому может быть неточным, но показывает идею собственного конструктора из SimpleIOC.
Затем в конструкторе модели представления вы можете вызвать метод service .Register, передавая себя в качестве параметра.
Это сохраняет "знания" в вашей модели представления, и ваш локатор остается сосредоточенным на том, что он должен делать.