Prism,用Unity连接Views和ViewModels,试图理解它

2024-03-20

使用 Unity 创建视图和视图模型

使用 Unity 作为依赖项注入容器类似于使用 MEF,基于属性的注入和基于构造函数的注入都是 支持的。主要区别在于这些类型通常是 在运行时没有隐式发现;相反,他们必须是 已向容器注册。

通常,您在视图模型上定义一个接口,以便视图 模型的具体具体类型可以与视图解耦。为了 例如,视图可以通过以下方式定义其对视图模型的依赖关系: 构造函数参数,如此处所示。 C#

public QuestionnaireView() 
{
    InitializeComponent(); 
}

public QuestionnaireView(QuestionnaireViewModel viewModel) : this() 
{
    this.DataContext = viewModel;
}

默认无参数 构造函数是允许视图在设计时工作所必需的 工具,例如 Visual Studio 和 Expression Blend。

或者,您可以在 视图,如此处所示。 Unity将实例化所需的视图模型 并在视图实例化后调用属性设置器。 C#

public QuestionnaireView() 
{
    InitializeComponent(); 
}

[Dependency] 
public QuestionnaireViewModel ViewModel 
{
    set { this.DataContext = value; } 
}

视图模型类型注册到Unity容器中,如图 这里。 C#

IUnityContainer container;
container.RegisterType<QuestionnaireViewModel>();

然后可以通过容器实例化视图,如图所示 这里。 C#

IUnityContainer container;
var view = container.Resolve<QuestionnaireView>();
  1. 如果我省略了有关注册 ViewModel 和实例化 View 的代码的最后一部分,并且仅使用此处将 ViewModel 挂接到 View 的两种方法之一(使用构造函数或使用属性),则似乎 ViewModel 和 View似乎一切正常。那么注册ViewModel和实例化View的代码需要什么呢?

  2. 第一个示例使用构造函数挂钩 View 和 ViewModel,完全没有提及 Unity,那么这里实际上使用了 Unity 吗?

  3. 与基于构造函数的注入相比,使用基于属性的注入是否有任何优点,或者它们是否完全相同?

  4. 文本的第一部分说“*通常,您在视图模型上定义一个接口,以便视图模型的特定具体类型可以与视图解耦”,然后给出一个示例。然而这个例子根本没有提到接口。这是怎么回事,我错过了什么吗?


回答问题 1 和 4

在您的示例中,视图模型的类型为QuestionnaireViewModel,这是一个具体的类。由于它是一个具体的类,因此当您使用以下命令解析视图时container.Resolve<QuestionnaireView>(),unity将通过调用为您实例化视图模型container.Resolve<QuestionnaireViewModel>()在幕后。

在这种情况下,注册视图模型是多余的。但是,当使用依赖注入时,您通常希望使用接口而不是类,因此您的构造函数将如下所示:

public QuestionnaireView(IQuestionnaireViewModel viewModel)
{
    this.DataContext = viewModel;
}

现在您的构造函数接收一个接口而不是一个类作为参数,Unity 不知道您要使用该接口的哪个实现。为了告诉 Unity,您需要将视图模型注册到容器:

container.RegisterType<IQuestionnaireViewModel, QuestionnaireViewModel>();

所以现在当你解析你的视图时,Unity将查找它应该使用哪个类作为实现IQuestionnaireViewModel,看到它是QuestionnaireViewModel并使用它。

回答问题2

正在使用Unity,因为为了让构造函数获取其参数,您需要使用容器解析视图。如果您自己实例化视图,则不会使用 Unitynew QuestionnaireView(),即不会发生构造函数或属性注入。

回答问题3

我认为这主要是关于什么更舒适以及您需要在哪里使用注射构件的问题。很多时候,您只想在构造函数中设置局部变量,而不是创建仅用于执行注入的属性。

不过,属性注入的一个好处是您可以使用container.BuildUp()使用创建的实例的方法new而不是container.Resolve<>()。这样,即使在创建之后,您也可以将成员注入到属性中 - 这是构造函数注入无法做到的事情。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Prism,用Unity连接Views和ViewModels,试图理解它 的相关文章

随机推荐

  • SSRS - 如何使 IIF 语句忽略无效值

    我正在使用 Business Intelligence 2008 在 SSRS 中创建一个表 我有一个日期 作为字符串 作为表中使用的值之一 该值可能有一个表示日期的字符串 也可能为空 如果它有一个值 我希望该值以不同的方式格式化 现在 我
  • Google 自定义搜索 API - 排序/过滤

    无论如何 是否可以通过页面标题标签或某些元标签来过滤结果 我阅读了文档 但一团糟 有人有想法吗 是的 您可以对自定义元标记进行排序和过滤 首先 将要过滤的数据放入元标签 https developers google com custom
  • iOS 4核心横向运动姿态

    我一直在尝试根据从 CMMotionManager 返回的 CMAttitude 旋转视图 特别是俯仰 x 和滚动 y 我用参考态度来设定我的视野 这对于纵向模式非常有效 但是当我尝试在横向视图中执行此操作时 它就出错了 由于手机现在逆时针
  • 隐藏 JSON.stringify() 输出中的某些值

    是否可以排除某些字段不包含在 json 字符串中 这是一些伪代码 var x x 0 y 0 divID xyz privateProperty1 foo privateProperty2 bar 我想排除 privateProperty1
  • 反转字符串,但不反转整数

    面试问题 反转字符串 但仅反转字母字符 整数应保持其原始位置 输入 abc12de 输出 edc12ba 输入 abcde79 输出 edcba79 输入 123ab456 输出 123ba456 下面是我的半工作代码 def revers
  • Razor 视图语法无法识别 HTML 属性中的“@”

    我正在将一个项目从 MVC 2 迁移到 MVC3 和 razor 视图引擎 在 MVC 2 中 我将有以下 html div div 使用剃刀时 我尝试了以下操作 它呈现文字文本 电子邮件受保护 cdn cgi l email protec
  • 如何使用 Coffee-Bytes 代码折叠

    如何使用 Coffee Bytes 代码折叠 http market eclipsesource com yoxos node com cb eclipse folding feature group 我想使用用户定义的区域 但不知道如何使
  • 如何在多个程序中接收相同的udp流?

    我有一个封闭的第三方系统 它发送单播 UDP 流 MPEG TS 我想在同一台计算机上的两个不同程序中访问该流 我无法更改源上的任何内容 甚至无法更改 IP 或端口 除了编写自己的小程序来捕获流然后创建新流并重新发送这两个流之外 还有其他选
  • 迁移以更改字段的默认值,并将所有现有记录的值更改为新的默认值(仅当它具有旧的默认值时)。

    我需要将字段的默认值从 0 更改为 3 但问题是我已经有数千条记录 并且希望这些记录仅当记录的默认值是 0 时才将值从 0 更改为 3 但对于其他值 例如1 2 应该保持不变 我该怎么做 在迁移中 您应该使用方法change column来
  • WebRTC 无法从 USB 输入设备获取视频源(readyState 转为结束)

    我正在尝试使用 WebRTC 在屏幕上显示视频输入作为实时源 我不想进行任何点对点通信或类似的事情 只是显示视频源 我的代码对于我的笔记本电脑集成网络摄像头工作得很好 但是当我连接外部视频输入设备 在本例中是一台旧摄像机 使用 StarTe
  • 如何在 Mac 上的 Chrome 中复制请求负载?

    最近我无法从以下位置复制已解析的请求负载Chrome 开发工具 按钮被禁用 我可以复制正常的 POST 和 GET 请求 但不能复制已解析的 JSON 负载 这是巨大的痛苦 有人知道解决方案吗 来到你的问题有同样的问题 我的解决方案 用鼠标
  • 应用程序布局中的渲染引擎

    背景 我正在创建一个由核心和多个模块组成的应用程序 这些模块是轨道引擎 并提供实际的功能 因为核心本身仅充当主机 引擎托管于 lib并安装在各自的路径上 coreApp lib module1 module2 etc 然后像这样安装模块 m
  • 增加 matplotlib 中的内部填充/边距

    如何增加 修改内边距 填充 用红色箭头标记的 绿色的可以增加subplots adjust 有没有办法改变内部的 红色 改变源和观察者之间的距离 ax dist 15 default is 10
  • 如何在 R 中安装 keras 包

    我正在尝试安装深度学习包keras在 RStudio 上使用这个website https blog rstudio com 2017 09 05 keras for r 我安装了keras using install packages k
  • 对象化 NoClassDefFoundError

    所以我刚刚使用 Google Eclipse 插件在 Eclipse Indigo 中创建了一个新的 GAME 项目 并且我只有以下 servlet public class TestServlet extends HttpServlet
  • Git 和 Visual Studio 项目参考

    好吧 我的问题的简短版本是 当您的项目在多个解决方案之间共享时 在 Git 中处理项目引用的最佳方法是什么 我的 Git 存储库应该如何组织 长版本是 我们是一个小型开发团队 5 名开发人员 目前我们使用 TFS 作为我们的源代码控制和构建
  • 当页面的数据上下文用于其他绑定时,如何绑定到 WPF 依赖属性?

    当页面的数据上下文用于其他绑定时 如何绑定到 WPF 依赖属性 简单的问题 需要设置元素的数据上下文 XAML
  • UITableView 自动尺寸无法正常工作

    我有一个表格视图 其中填充了来自 Firebase 的数据 但是 当使用自动尺寸调整表格视图大小时 某些文本会被截断 这是我的故事板 约束设置为顶部 底部 右侧和左侧 当没有大量文本时 它工作正常 如此处所示 但是 当我用大量文本填充单元格
  • 谷歌地图 API v3 - 最近的街景

    当某个地点无法使用街景时 我想找到最近的有街景的地点 我能想到的唯一办法就是 radius 0 noOfPoints 3 while radius lt 10 miles radius radius 0 2 miles points cal
  • Prism,用Unity连接Views和ViewModels,试图理解它

    使用 Unity 创建视图和视图模型 使用 Unity 作为依赖项注入容器类似于使用 MEF 基于属性的注入和基于构造函数的注入都是 支持的 主要区别在于这些类型通常是 在运行时没有隐式发现 相反 他们必须是 已向容器注册 通常 您在视图模