模块化整体中的跨模块通信

Gue*_*lla 6 c# architecture design-patterns asp.net-core modular-monolith

我在本文中学习了模块化整体项目结构:https://codewithmukesh.com/blog/modular-architecture-in-aspnet-core

其中大部分对我来说是有意义的,但我不太明白的是:

跨模块通信只能通过接口/事件/内存总线进行。跨模块数据库写入应保持最小或完全避免。

跨模块通信究竟是什么样子的?

假设我有 3 个模块:

  • 产品
  • 用户
  • 安全

我的安全模块注册了一个端点DisableUser。此端点的工作是更新UserProduct处于禁用状态的用户关联的所有信息。

模块如何在工作单元中Security调用User和更新状态方法?Product

我的理解是,这种模式的目的是让以后更容易地将模块提取到微服务,所以我想将其作为某种任务可以更容易地更改为消息代理,但我只是不确定如何这应该看起来。

我的例子显然是人为的,我的主要观点是当涉及读/写时模块如何一起通信?

pic*_*ino 10

理论

这类问题对术语有很多误解,所以我们来标记2种完全不同的架构——单体架构微服务架构。因此,介于这两者之间的一种架构是模块化整体架构

单体架构大多存在一个巨大的问题——高耦合和低内聚,因为你没有强有力的方法来避免它。因此,程序员决定考虑构建不同架构的新方法,以使其很难陷入高耦合低内聚问题。

微服务架构是一种解决方案(尽管它也解决了其他问题)。微服务架构的要点在于将服务彼此分离以避免高耦合(因为在服务之间建立通信并不像单体架构那么容易)。

但程序员无法“一键”从一种架构转变为完全不同的架构,因此从单体架构构建微服务架构的一种(但不仅仅是一种)方法是首先制作模块化单体(只是解决高耦合低内聚问题,但在monolith),然后轻松地将模块提取到微服务中。

沟通

为了降低耦合度,我们应该关注服务之间的通信。让我们使用您在问题中放入的示例。

想象一下我们有这样的整体架构: 整体式架构

我们在这里肯定看到了高耦合问题。假设我们想要将其构建得更加模块化。为此,我们需要在模块之间添加一些东西来将它们彼此分开,而且我们希望模块能够通信,所以我们唯一需要添加的是总线。

像这样的东西: 在此输入图像描述

PS 可以完全分离而不是内存总线(如kafka或rabbitmq)

所以你的主要问题是如何在模块之间进行通信,有几种方法可以做到这一点。

接口通讯(同步方式)

模块可以通过接口直接(同步)相互调用。接口是一个抽象,所以我们不知道该接口背后是什么。它可以是模拟的或真实的工作模块。这意味着一个模块对其他模块一无所知,它只知道与其通信的一些接口。

public interface ISecurityModule { }
public interface IUserModule { }
public interface IProfileModule { }

public class SecurityModule : ISecurityModule
{
    public SecurityModule(IUserModule userModule) { } // Does not know about UserModule class directly
}

public class UserModule : IUserModule
{
    public UserModule(IProfileModule profileModule) { } // Does not know about ProfileModule class directly
}

public class ProfileModule : IProfileModule
{
    public ProfileModule(ISecurityModule securityModule) { } // Does not know about SecurityModule class directly
}
Run Code Online (Sandbox Code Playgroud)

毫无疑问,接口之间可以通过方法调用进行通信,但这种方案并不能很好地解决高耦合问题。

通过总线通讯(异步方式)

总线是在模块之间建立通信的更好方法,因为它强制您使用事件/消息/命令来进行通信。您不能再直接使用方法调用。

为了实现这一点,您应该使用一些总线(单独的或内存中的库)。我建议检查其他问题(例如),以找到为您的架构构建此类通信的正确方法。

但请注意 - 使用总线可以使模块之间的通信异步,因此它迫使您重写内部模块行为以支持这种通信方式。

关于您的DisableUser端点示例。SecurityModule可以只在总线中发送用户在安全模块中被禁用的命令/事件/消息 - 因此其他服务可以处理此命令/事件/消息并使用当前模块逻辑“禁用”它。

下一步是什么

接下来是一个微服务架构,其中完全独立的服务也通过独立的总线与独立的数据库进行通信: 在此输入图像描述

例子

不久前,我在课程结束后完全完成了微服务架构的项目。在这里
检查一下如果您需要良好的微服务架构示例,

图像是使用 Excalidraw 创建的