【问题标题】:Avoiding circular references for 2-way communication between projects避免项目之间双向通信的循环引用
【发布时间】:2020-05-25 07:46:40
【问题描述】:

我正在构建一个类似于 i3wm/bspwm 的开源平铺窗口管理器应用程序。 Would hopefully look something like this, but for Windows。屏幕顶部有一个小栏显示您的“工作区”,您可以单击工作区以显示其窗口。

目前,我的解决方案中有 3 个项目:Bar、Window Manager 和 Common。 Window Manager 项目保存工作区等的状态,并具有 Bar 应该触发的命令。 Common 仅保留两个项目之间共享的基础架构,例如 CommandBus,以促进项目之间的通信。

Bar 项目由以下内容组成:

public LaunchBar()
{
    // Launch WPF app.
    InitializeComponent();

    // Bind current workspaces to template.
    workspaces.ItemsSource = workspaceRepository.GetWorkspaces(); // workspaceRepository exists in Window Manager project
}

private void OnWorkspaceClick()
{
    commandBus.Invoke(new ChangeWorkspaceCommand()); // ChangeWorkspaceCommand exists in Window Manager project
}

这个想法是LaunchBar 在检测到新监视器时在窗口管理器项目中以编程方式调用。但是,这会导致两个项目之间出现循环引用。

如何构建这个项目以避免循环引用?天哪,卡在这里了。

【问题讨论】:

    标签: c# architecture domain-driven-design cqrs


    【解决方案1】:

    您需要将 WindowManagerBar 解耦。

    如果Bar需要访问窗口管理器功能。使用事件/委托并让窗口管理器订阅,以便它可以在Bar 上执行所需的任何操作。或者创建一个它们之间通用的接口,以便您可以将该合同传递给 bar。

    无论哪种方式,您都需要以逻辑依赖项目只负责在该级别对他们有意义的责任进行重构。

    想想看,建筑工人雇了一个瓦工。瓦工没有也不应该对建筑商使用的会计软件有任何了解,他只是在工作完成(事件)后退还发票,他不打电话输入发票,或在账目上向承包商付款软件。会计女士做她需要的事情,并给瓦工(或其他什么)工资。

    简而言之,瓦工有一个事件,或者他们共享一个预定的通用合约(接口),也就是说,如果 bar 有一个IWindowManager 接口,它可以调用 GetWorkspaces()。

    无论如何,只有你有能力在没有循环引用的情况下逻辑拆分它,什么对你有意义

    【讨论】:

    • 非常感谢,我想我现在对如何解耦我的项目有了一些想法。我的想法是本质上将Window Manager 项目重命名为Domain,并将其在启动时运行的逻辑移动到它自己的项目(然后可能称为Window Manager)。这样我的依赖流将是Common -> Domain -> Window Manager/Bar
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 2018-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多