c# - 循环依赖和控制反转 - 如何解决这些问题?

标签 c# wpf mvvm dependency-injection circular-dependency

在我的应用程序(基于 MVVM 架构的 WPF 应用程序)中,我使用了很多 ICommand s 作为服务。其中一些命令可以绑定(bind)到菜单项、工具栏、状态栏等,它们被注入(inject)到相应的容器 View 模型中。现在,它们中的一些例如能够在应用程序的 Shell 上操作数据,因此 Shell 是它们的依赖项。由于 Shell 还托管所述容器(菜单、状态栏...),因此我得到了循环依赖。 (外壳 -> 菜单 -> 命令 -> 外壳)。

目前,我使用 MEF 来编写我的应用程序,所以大多数时候问题可以通过属性或私有(private)成员注入(inject)来解决,但我觉得这是一种令人讨厌的做法(服务无法告诉 parent 它需要这种依赖,即使它确实如此)。

我的问题是:解决此类问题的常用方法是什么:

class Shell : IShell
    .ctor(IMenu)

class Menu : IMenu
    .ctor(ICommand[])

 class ExitCommand : ICommand
    .ctor(IShell)

最佳答案

我从未使用过 MEF,但确实使用了依赖注入(inject)容器并且遇到了类似的问题。问题是,(我认为)您将 Shell 作为服务扔掉(提供退出功能),但它也充当 ViewModel(显示菜单等)。它承担了本应承担的更多责任。

让我们将包罗万象的“IShell”接口(interface)拆分为单独的模块来演示:

class Shell : IShell, IExitManager
    .ctor(IMenu)

class Menu : IMenu
    .ctor(ICommand[])

 class ExitCommand : ICommand
    .ctor(IExitManager)

你的 shell 同时做两件事,它是 ViewModel 的东西 (IShell) 和它正在管理退出 (IExitManager)。

我要做的是从您的 ViewModel 中抽象出功能。我会创建一个专用的 IExitManager服务。而不是制作 ShellViewModel实现这个功能,并将整个东西注入(inject)到只需要触发退出事件的地方(拖动菜单功能并导致循环依赖),而是将该功能放在专用的IExitManager中。 .

而不是您当前的:

enter image description here

而是将服务带出 Shell 实现:

enter image description here

您的类(class)IExitManager将需要公开与您目前在 IShell 中拥有的相同功能(我假设是 Exit() 方法)和事件处理程序 ExitRequestedHandler让您的 Shell 监听并执行它的操作。

EventAggregator 基本上是一个更通用的版本——我建议你看一下。你可以让你的 Shell 监听 EventExit 事件,然后你的命令发出它们。唯一常见的依赖项是 EventAggregator 服务。该解决方案所做的是仅针对退出事件的“一次性”版本。如果您经常这样做,请使用 EventAggregator。

关于c# - 循环依赖和控制反转 - 如何解决这些问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41474188/

相关文章:

c# - 组织大型 C# 解决方案

c# - 应用程序更新时的 UWP BackgroundTask

c# - Xamarin 表格 : Resource strings

c# - XAML - 为什么数据绑定(bind) TwoWay 不适用于 .net 4.0 中组合框的文本属性?

events - 如何在另一个项目中使用 xaml 和 viewmodel

c# - 如何在 WPF 中将标签文本居中?

c# - 子项目的 TreeView ItemContainerStyle,FullRowSelect

c# - ClickOnce 在重新安装期间不替换 App_Data 文件

wpf - 绑定(bind) slider 控件的事件

c# - 每个字典条目都必须有一个关联的键属性