避免项目间双向通信的循环引用

Avoiding circular references for 2-way communication between projects

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

目前,我的解决方案中有 3 个项目:Bar、Window Manager 和 Common。 Window Manager 项目保存工作区的状态等,并具有 Bar 应该触发的命令。 Common 仅包含 2 个项目之间共享的基础设施,例如 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 在 Window Manager 项目中以编程方式调用。但是,这会导致两个项目之间的循环引用。

我怎样才能构建这个项目以避免循环引用?真他妈卡在这里。

您需要将 WindowManagerBar 分离。

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

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

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

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

无论如何,只有你有能力在没有循环引用的情况下将其逻辑拆分,并且对你有意义