WPF - Использование поведений для создания экземпляров модели представления и сервисов
Я пытаюсь найти лучшую практику для создания моделей представления и служб (служба просто общается с сервером и возвращает данные обратно в модель представления). Я видел 2 разных подхода.
- Использование локатора модели представления
- Использование поведения (я не уверен, что это хороший подход)
Для второго подхода вы определяете поведение для UserControl, а для события присоединения вы создаете экземпляр модели представления и экземпляр службы и складываете их все вместе.
protected override void OnAttached()
{
var service = Activator.CreateInstance(ServiceType)
var viewModel = Activator.CreateInstance(ModelType);
base.AssociatedObject.DataContext = viewModel;
base.OnAttached();
}
и в вашем usercontrol xaml
<i:Interaction.Behaviors>
<be:ViewModelBehavior ViewModelType="{x:Type vm:ViewModel1}" ServiceType="{x:Type serv:Service1}"/>
</i:Interaction.Behaviors>
Это хорошее использование поведения, или я должен просто использовать шаблон локатора viewmodel.
1 ответ
У вашего поведения есть один существенный недостаток - в каждом пользовательском контроле вы должны указать поведение ViewModelType (и ServiceType также).
Вы можете сделать следующее:
<UserControl x:Class="MyApp.HomePage" ....
local:ViewModelLocator.AutoWireViewModel="True">
...
</UserControl>
Когда вы устанавливаете для присоединенного свойства значение true, ViewModelLocator
создаст экземпляр viewmodel и назначит его для контекста данных usercontrol. ViewModelLocatator
использует соглашение об именах для определения типа модели представления. В этом случае это может быть HomePageViewModel
потому что тип представления HomePage
,
Этот подход используется PRISM ViewModelLocator из библиотеки Prism.Mvvm, но я рекомендую вам написать свой собственный, поскольку он довольно прост.
Это в основном похоже на ваш ViewModelBehavior
Но есть два отличия:
Поведение реализовано как прикрепленное свойство. Он позволяет вам определять поведение в стиле, поэтому он будет применяться к любому пользовательскому контролю, который использует этот стиль. Вы не можете указать Interaction.Behaviors в стилях.
Он использует соглашение об именах вместо явно установленного ViewModelType
Что касается сервиса, который должен быть передан в качестве параметра для viewmodel: Вы можете использовать шаблон IoC. Это псевдокод, который описывает шаблон:
public class MyViewModel(IMyService service) {...}
//at application startup you setup the IoC container:
IoC.Setup<IMyService>(new MyService());
//later
var viewModel = IoC.GetInstance<MyViewModel>(); //MyService will be passed as to ctor