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,试图理解它 的相关文章

  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • 将数组向左或向右旋转一定数量的位置,复杂度为 o(n)

    我想编写一个程序 根据用户的输入 正 gt 负 include
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • 将布尔参数传递给 SQL Server 存储过程

    我早些时候问过这个问题 我以为我找到了问题所在 但我没有 我在将布尔参数传递给存储过程时遇到问题 这是我的 C 代码 public bool upload false protected void showDate object sende
  • WPF 中的调度程序和异步等待

    我正在尝试学习 WPF C 中的异步编程 但我陷入了异步编程和使用调度程序的困境 它们是不同的还是在相同的场景中使用 我愿意简短地回答这个问题 以免含糊不清 因为我知道我混淆了 WPF 中的概念和函数 但还不足以在功能上正确使用它 我在这里
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • 在 Visual Studio 2008 上设置预调试事件

    我想在 Visual Studio 中开始调试程序之前运行一个任务 我每次调试程序时都需要运行此任务 因此构建后事件还不够好 我查看了设置的 调试 选项卡 但没有这样的选项 有什么办法可以做到这一点吗 你唯一可以尝试的 IMO 就是尝试Co
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • WPF TabControl,用C#代码更改TabItem的背景颜色

    嗨 我认为这是一个初学者的问题 我搜索了所有相关问题 但所有这些都由 xaml 回答 但是 我需要的是后台代码 我有一个 TabControl 我需要设置其项目的背景颜色 我需要在选择 取消选择和悬停时为项目设置不同的颜色 非常感谢你的帮助
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • Web API - 访问 DbContext 类中的 HttpContext

    在我的 C Web API 应用程序中 我添加了CreatedDate and CreatedBy所有表中的列 现在 每当在任何表中添加新记录时 我想填充这些列 为此目的我已经覆盖SaveChanges and SaveChangesAsy
  • 在数据库中搜索时忽略空文本框

    此代码能够搜索数据并将其加载到DataGridView基于搜索表单文本框中提供的值 如果我将任何文本框留空 则不会有搜索结果 因为 SQL 查询是用 AND 组合的 如何在搜索 从 SQL 查询或 C 代码 时忽略空文本框 private
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • for循环中计数器变量的范围是多少?

    我在 Visual Studio 2008 中收到以下错误 Error 1 A local variable named i cannot be declared in this scope because it would give a
  • 使用 DataBindingComponent 的 Inflate 方法

    当 Glide 成功渲染图像后 我在更新文本视图时看到此错误 致命异常 java lang IllegalStateException 必需 CustomBinding 类中的 DataBindingComponent 为 null 绑定适
  • 实体框架 4 DB 优先依赖注入?

    我更喜欢创建自己的数据库 设置索引 唯一约束等 使用 edmx 实体框架设计器 从数据库生成域模型是轻而易举的事 现在我有兴趣使用依赖注入来设置一些存储库 我查看了 StackOverflow 上的一些文章和帖子 似乎重点关注代码优先方法
  • 将 xml 反序列化为类,list<> 出现问题

    我有以下 XML
  • x86 上未对齐的指针

    有人可以提供一个示例 将指针从一种类型转换为另一种类型由于未对齐而失败吗 在评论中这个答案 https stackoverflow com questions 544928 reading integer size bytes from a
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐

  • 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 基于属性的注入和基于构造函数的注入都是 支持的 主要区别在于这些类型通常是 在运行时没有隐式发现 相反 他们必须是 已向容器注册 通常 您在视图模