ViewModelLocator MVVM Light中的ViewModels

fex*_*fex 33 xaml mvvm-light

将所有ViewModel存储在SimpleIoc中是否正确?例如,我有三页MainPage,照片,目录(因此有三个ViewModels - > MainVM,PhotosVM,DirectoriesVM).我应该将每个页面中的DataContext设置为ViewModelLocator中的View Model属性,还是将ViewModel嵌套为MainVM中的属性,并将每个页面DataContext绑定到Main.PhotosVMProperty,Main.DirectoriesVMProperty等等?谁能解释一下IoC的想法和目的?

Fas*_*ons 125

首先,让我们看一下ViewModelLocator的作用以及我们使用它的原因:

ViewModelLocator在App.xaml页面上声明为对象,是一个应用程序单例.我们将会运行一个,并且只有一个可用于应用程序.

ViewModelLocator是MVVM Light中所有ViewModel的源代码.对于每个ViewModel,我们在ViewModelLocator上都有一个属性,允许我们为View获取ViewModel.此代码如下所示:

public class ViewModelLocator
{
    public MainPageViewModel MainPage
    {
        get { return new MainPageViewModel(); }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的App.xaml的一部分:

<Application.Resources>
    <vm:ViewModelLocator
        x:Key="ViewModelLocator" />
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)

这是View.xaml的一部分

DataContext="{Binding MainPage, Source={StaticResource ViewModelLocator}}"
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.要回答你的第一个问题,你是否必须在MVVM Light中使用Ioc?不.没有必要,因为ViewModelLocator完全构建和实例化了您的视图模型.

现在,关于第二个问题:IoC的目的是什么?

IoC旨在允许您执行以下操作:

使用Mvvm Light,你可以这样做:

public class ViewModelLocator
{
    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        if (ViewModelBase.IsInDesignModeStatic)
        {
            SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
        }
        else
        {
            SimpleIoc.Default.Register<IDataService, DataService>();         
        }

        SimpleIoc.Default.Register<MainViewModel>();
    }

    public MainViewModel Main
    {
        get { return SimpleIoc.Default.GetInstance<MainViewModel>(); }
    }
}

public class MainViewModel
{
    public ObservableCollection<Foo> Foos { get; set; }

    public MainViewModel(IDataService dataService)
    {
        _dataService=dataService;
        Foos=_dataService.GetFoos();
    }
}
Run Code Online (Sandbox Code Playgroud)

当我打电话时解析我的MainViewModel

SimpleIoc.Default.GetInstance<MainViewModel>()
Run Code Online (Sandbox Code Playgroud)

内部发生的事情是SimpleIoc检查MainViewModel是否具有任何依赖关系(其构造函数中的参数).然后,它会尝试通过查看已向其注册的接口来解析这些参数.它以递归方式执行此操作,因此如果DataService具有依赖关系,则它将被实例化并在实例化时传递给DataService构造函数.

我为什么要做这一切呢?

  1. 使您的课程易于单元测试
  2. 使您的代码界面驱动.这意味着您引用的是接口而不是具体的类
  3. 使代码松散耦合.这意味着有人可以更改接口的实现,并且使用该接口的类不关心,也不必重新编码.
  4. 以自动方式解析类依赖项.
  5. 在MVVM Light中,您将看到它可以告诉它何时在design-mode(ViewModelBase.IsInDesignModeStatic)中运行,这意味着您可以创建设计时服务来提供视图模型数据,以便Visual Studio中的View包含实际数据.

  • ...如果你想知道你的输入是否会影响年限,那是的.这正是*完全*那种细分和走过,帮助我了解正在发生的事情.谢谢! (2认同)