【问题标题】:best way to switch between using implementations of interface in ViewModel在 ViewModel 中使用接口实现之间切换的最佳方法
【发布时间】:2018-06-14 14:11:08
【问题描述】:

我有一个使用 MVVM 模式的 WPF 项目。我有一个接口,为此我将调用 IMyData,我目前有 myDataImplAmyDatImplB 的 2 个实现。我希望我的 ViewModel 能够在使用这两种实现之间动态切换。目前,我将接口的两种实现都传递到 ViewModel 的构造函数中,并具有 Boolean 属性,其中 View 中的 ToogleButton 被绑定以确定使用哪一个。我觉得可能有更好的方法来做到这一点,并且传入 IMyData 的两个实现只是感觉不对。此外,如果我最终获得了 IMyData 的第三个实现,我当前使用布尔值来确定要使用的 IMyData 实现的方法将不起作用。

界面可以从视图中即时更新,但这会破坏 MVVM,因为我认为这需要在我的视图中进行额外的代码隐藏。我正在寻找适合 MVVM 的更具可扩展性的解决方案。

【问题讨论】:

  • 为什么不用属性注入代替构造函数注入呢?然后,您可以随时将该属性设置为接口的任何实现。
  • 我可以通过在视图中绑定 UI 控件来进行属性注入吗?请发布一个简短的示例或一些伪代码。

标签: c# wpf mvvm viewmodel


【解决方案1】:

您认为这是错误的,IMO 是准确的。实现IMyData 的全部原因应该是完全避免这种行为。

我不确定您是如何设置项目的,但只是为了帮助您解决此逻辑,请考虑 ViewModel 只是业务逻辑不存在的端点。您的 ViewModel 应该与 DAL(数据访问层)通信,在这种情况下,将抽出它更新的模型信息。

由于您使用的是接口,因此 DAL 应该提供实例化到 ViewModel 的接口。在 ViewModel 中实现仅指示状态的命令 (ICommand),例如枚举。告诉 DAL 你想要哪个状态。当 DAL 更新时,您的 ViewModel 应该正在监听并对其做出反应。此时,ViewModel 会更新 IMyData 属性,该属性应该通知侦听器,并且 View 将自动更改(如果一切都正确连接。)。

这可能听起来令人困惑,所以我将尝试以不同的方式简化。

不惜一切代价将参考文献保持在单向方向。

View -> ViewModel -> DAL(DAL 被认为是 MVVM 中的模型,在你的情况下它会抽出 IMyData)。

让 View 绑定到 ViewModel 中的一个命令,例如它是否需要 StateN。

ViewModel 然后告诉 DAL 切换到 StateN 或自动查找 StateN 模型。

DAL 然后将 IMyData 类型更改为在 StateN 中工作的类型。

ViewModel 正在监听 DAL 的更改,当 DAL 说 StateNChanged 时,ViewModel 会更新 DAL 的 IMyData 属性,这会触发通知。

View 绑定到 ViewModel,然后根据新数据进行更新。

如果这没有意义,请发布大部分代码,我会进行修改并展示它。

【讨论】:

  • 是的,这正是我想做的,但我不知道我可以使用命令来实现它。
  • 让我看看是否可以使用 ViewModel 中的示例 ICommand 更新答案,并希望它有意义。
  • 谢谢迈克尔,我们将不胜感激!
  • 我为您整理了一个名为 WPF_ICommand_Example 的完整项目示例,它从头开始基于这个问题。你可以把它拆开,问尽可能多的问题,但我想通过电子邮件发送给你。我的电子邮件是 michael_puckett_ii@hotmail.com 任何对这个问题感兴趣的人也可以提出要求。如果需要,我会把它扔到 GitHub 上。
【解决方案2】:

视图模型不应依赖于IMyData 接口的任何实现。它应该只依赖于接口本身。

由于您希望能够在运行时动态切换实现,您可以向视图模型添加一个属性,以提供默认且可互换的实现:

public IMyData CurrentImplementation { get; set; } = new myDataImplA();

视图或任何其他组件可以根据需要通过简单地设置此属性来切换实现。

【讨论】:

  • 我同意这一点,但这是我在帖子末尾提到的那种解决方案:“界面可以从视图中即时更新,但这会破坏 MVVM,因为我认为这需要在我的视图中进行额外的代码隐藏。” 您的示例没有演示如何在 MVVM 模式中执行此操作。
  • 您是说绑定到或设置视图模型的属性会破坏 MVVM 模式...?你在这里指的是什么样的实现?视图可以注入视图模型。请澄清您的问题。
  • 我同意这样做很好,但是我在一个严格的环境中工作,我不应该在 View 的代码隐藏中放置很多东西。我可以使用绑定进行注射吗?
  • 是的,当然。它只是一个可以绑定的属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-23
  • 2016-08-27
  • 2018-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多