Должен ли локатор 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, передавая себя в качестве параметра.

Это сохраняет "знания" в вашей модели представления, и ваш локатор остается сосредоточенным на том, что он должен делать.

Другие вопросы по тегам