【问题标题】:Avoid circular refence while classes have to communicate with eachother (Dependency injection)避免循环引用整个类必须相互通信(依赖注入)
【发布时间】:2021-11-30 07:52:43
【问题描述】:

我正在开发一个用 C# 和 WPF 编写的应用程序。

有一个布局由三个独立的部分(子视图)组成。

  • 包含当前主要内容的“内容”视图(例如,产品列表视图)。
  • 位于其顶部的视图,包含工具和选项 控件。
  • 左侧的主菜单视图。

我为我的应用程序使用 .NET 依赖注入(Microsoft.Extensions.DependencyInjectionMicrosoft.Extensions.Configuration.Abstractions

当为内容视图设置 ViewModel 时,我还想为顶视图设置一个 ViewModel。这些 ViewModel 必须相互通信/引用。 就像,当执行顶部 ViewModel 上的命令时,应该通知内容 ViewModel 和/或做某事,反之亦然。 假设我有一个TopViewModel 和一个ContentViewModel。 我可以做的一件坏事是:

  • TopViewModel 的构造函数中需要ContentViewModel
  • 并要求ContentViewModel 的构造函数中的TopViewModel

当然不行,因为它是循环引用。

我能想到的替代方案是,只需要在ContentViewModel 的构造函数中使用TopViewModel,并且不要对其他类做同样的事情。 然后ContentViewModel 的构造函数代码可以监听TopViewModel 的事件。 TopViewModel 对ContentViewModel 一无所知,如果出于某种逻辑原因需要引用它,这可能是个问题。

某些内容视图可以有多个顶视图(它们会随着用户选择某些内容而改变)

我对此很认真。我能想到的一切对我来说都是丑陋和糟糕的做法。虽然我认为这是一个非常简单和常见的情况。 在不违反 OOP 规则的情况下,最好的、普遍接受的解决方案是什么?

【问题讨论】:

  • 在父视图模型中构造子视图模型而不是使用 di 生成它们是很常见的。如果这行不通,那么我会考虑将绑定作为我跨越任何边界的第一个候选者。
  • 这看起来像是中介者模式的候选者在两个视图模型之间传递命令
  • 类之间不必直接通信。我会使用事件聚合器在不同的类之间进行通信。然后,每个类只知道这个事件聚合器,并且可以发布和监听他们想要的任何事件。

标签: c# wpf design-patterns mvvm dependency-injection


【解决方案1】:

不违反 OOP 规则的最佳、普遍接受的解决方案是什么?

您应该考虑使用事件聚合器以松散耦合的方式在视图模型之间进行通信,而不是存储从一个视图模型到另一个视图模型的直接引用。

这消除了视图模型类之间的紧密耦合,并使您的应用程序更易于维护和随着时间的推移而发展。

这个想法是订阅者观察事件聚合器而不是发布者,并且发布者只知道事件聚合器而不知道订阅者。有关详细信息,请参阅以下博客文章。

Using the event aggregator pattern to communicate between view models

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    • 1970-01-01
    • 2014-07-27
    • 2013-02-06
    • 1970-01-01
    相关资源
    最近更新 更多