什么是 ViewModelLocator,与 DataTemplates 相比,它的优缺点是什么? [英] What is a ViewModelLocator and what are its pros/cons compared to DataTemplates?

查看:31
本文介绍了什么是 ViewModelLocator,与 DataTemplates 相比,它的优缺点是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以快速总结一下 ViewModelLocator 是什么、它是如何工作的,以及与 DataTemplates 相比使用它的优点/缺点是什么?

Can someone give me a quick summary of what a ViewModelLocator is, how it works, and what the pros/cons are for using it compared to DataTemplates?

我曾尝试在 Google 上查找信息,但似乎有许多不同的实现方式,并且没有明确列出它是什么以及使用它的利弊.

I have tried finding info on Google but there seems to be many different implementations of it and no striaght list as to what it is and the pros/cons of using it.

推荐答案

Intro

在 MVVM 中,通常的做法是让视图通过从 依赖注入 (DI) 容器.当容器被要求提供(解析)一个 View 类的实例时,这会自动发生.容器通过调用接受 ViewModel 参数的 View 构造函数将 ViewModel 注入到 View 中;这种方案称为控制反转 (IoC).

Intro

In MVVM the usual practice is to have the Views find their ViewModels by resolving them from a dependency injection (DI) container. This happens automatically when the container is asked to provide (resolve) an instance of the View class. The container injects the ViewModel into the View by calling a constructor of the View which accepts a ViewModel parameter; this scheme is called inversion of control (IoC).

这里的主要好处是可以在运行时配置容器,并提供有关如何解析我们从它请求的类型的说明.这允许通过指示它解析我们在应用程序实际运行时使用的类型(视图和视图模型)来实现更高的可测试性,但在运行应用程序的单元测试时以不同的方式指示它.在后一种情况下,应用程序甚至不会有 UI(它没有运行;只有测试)所以容器将解析 mocks 代替应用程序运行时使用的普通"类型.

The main benefit here is that the container can be configured at run time with instructions on how to resolve the types that we request from it. This allows for greater testability by instructing it to resolve the types (Views and ViewModels) we use when our application actually runs, but instructing it differently when running the unit tests for the application. In the latter case the application will not even have a UI (it's not running; just the tests are) so the container will resolve mocks in place of the "normal" types used when the application runs.

到目前为止,我们已经看到,DI 方法通过在应用程序组件的创建上添加一个抽象层,可以轻松地对应用程序进行测试.这种方法有一个问题:它不适用于视觉设计师,例如 Microsoft Expression Blend.

So far we have seen that the DI approach allows easy testability for the application by adding an abstraction layer over the creation of application components. There is one problem with this approach: it doesn't play well with visual designers such as Microsoft Expression Blend.

问题在于,在正常的应用程序运行和单元测试运行中,必须有人设置容器,并说明要解决的类型;此外,有人必须要求容器解析视图,以便可以将视图模型注入其中.

The problem is that in both normal application runs and unit test runs, someone has to set up the container with instructions on what types to resolve; additionally, someone has to ask the container to resolve the Views so that the ViewModels can be injected into them.

然而,在设计时没有我们的代码运行.设计者尝试使用反射来创建我们的视图的实例,这意味着:

However, in design time there is no code of ours running. The designer attempts to use reflection to create instances of our Views, which means that:

  • 如果 View 构造函数需要一个 ViewModel 实例,设计者将根本无法实例化 View -- 它会以某种受控方式出错
  • 如果视图有一个无参数的构造函数,视图将被实例化,但它的 DataContext 将是 null 所以我们将在设计器中得到一个空"视图 -- 这不是很有用
  • If the View constructor requires a ViewModel instance the designer won't be able to instantiate the View at all -- it will error out in some controlled manner
  • If the View has a parameterless constructor the View will be instantiated, but its DataContext will be null so we 'll get an "empty" view in the designer -- which is not very useful

ViewModelLocator 是一个额外的抽象,像这样使用:

The ViewModelLocator is an additional abstraction used like this:

  • 视图本身实例化一个 ViewModelLocator 作为其资源的一部分和将其 DataContext 绑定到定位器的 ViewModel 属性
  • 定位器以某种方式检测我们是否处于设计模式
  • 如果不在设计模式下,定位器将返回一个从 DI 容器解析的 ViewModel,如上所述
  • 如果在设计模式下,定位器使用自己的逻辑返回一个固定的虚拟"ViewModel(记住:设计时没有容器!);这个 ViewModel 通常预先填充了虚拟数据
  • The View itself instantiates a ViewModelLocator as part of its resources and databinds its DataContext to the ViewModel property of the locator
  • The locator somehow detects if we are in design mode
  • If not in design mode, the locator returns a ViewModel that it resolves from the DI container, as explained above
  • If in design mode, the locator returns a fixed "dummy" ViewModel using its own logic (remember: there is no container in design time!); this ViewModel typically comes prepopulated with dummy data

当然,这意味着 View 必须有一个无参数的构造函数才能开始(否则设计者将无法实例化它).

Of course this means that the View must have a parameterless constructor to begin with (otherwise the designer won't be able to instantiate it).

ViewModelLocator 是一种习惯用法,可让您在 MVVM 应用程序中保留 DI 的优势,同时还允许您的代码与视觉设计师一起玩得很好.这有时称为应用程序的可混合性"(指 Expression Blend).

ViewModelLocator is an idiom that lets you keep the benefits of DI in your MVVM application while also allowing your code to play well with visual designers. This is sometimes called the "blendability" of your application (referring to Expression Blend).

消化完以上,看一个实际例子此处.

After digesting the above, see a practical example here.

最后,使用数据模板不是使用 ViewModelLocator 的替代方法,而是对部分 UI 使用显式 View/ViewModel 对的替代方法.通常,您可能会发现不需要为 ViewModel 定义视图,因为您可以使用数据模板来代替.

Finally, using data templates is not an alternative to using ViewModelLocator, but an alternative to using explicit View/ViewModel pairs for parts of your UI. Often you may find that there's no need to define a View for a ViewModel because you can use a data template instead.

这篇关于什么是 ViewModelLocator,与 DataTemplates 相比,它的优缺点是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆