WPF - Использование поведений для создания экземпляров модели представления и сервисов

Я пытаюсь найти лучшую практику для создания моделей представления и служб (служба просто общается с сервером и возвращает данные обратно в модель представления). Я видел 2 разных подхода.

  1. Использование локатора модели представления
  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 Но есть два отличия:

  1. Поведение реализовано как прикрепленное свойство. Он позволяет вам определять поведение в стиле, поэтому он будет применяться к любому пользовательскому контролю, который использует этот стиль. Вы не можете указать Interaction.Behaviors в стилях.

  2. Он использует соглашение об именах вместо явно установленного 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
Другие вопросы по тегам