Windows 服务的六角形 Architecture/Ports 和适配器架构。正确的路?
Hexagonal Architecture/Ports and Adapter Architecture for Windows Services. Right way?
我阅读了有关 Alistair Cockburn 提出的端口和适配器架构的不同来源,发现它适合我开发网关服务应用程序的场景,该应用程序从多个源接收消息并处理消息并将消息发送到多个目的地。这是我的详细实现。
- 目前消息来源是单一的(JMS Queue)
- JMS 端口订阅 JMS 消息队列并将其传递给 JMS 适配器,后者又调用相应的消息处理程序。
- 消息处理程序依次调用业务域层,该层独立于消息的来源或目的地,如 cockburn 所提议的。
- 具有依赖注入容器注入的 JMS 端口、WCF 端口、DB 端口、TCP 端口的消息处理程序依次调用 JMS 端口、TCP 端口和 WCF 端口以 publish/send 域处理的消息。
如果我是否偏离了 Cockburn 提出的架构,我有几个关键questions/doubts。
- 单个端口能否同时处理 inflow/outflow 消息(在本例中为 JMS 端口)。还是为消息的流入和流出设置单独的端口是一个好习惯。
2.As 根据 cockburn 的文章
入站通信:"As events arrive from the outside world at a port, a technology-specific adapter converts it into a usable procedure call or message and passes it to the application."
出站通信:"When the application has something to send out, it sends it out through a port to an adapter, which creates the appropriate signals needed by the receiving technology (human or automated)."
所以我将处理后的消息直接传递到端口,该端口又调用适配器根据目标要求转换消息。
Message Handlers(Application Layer)是否可以依赖注入的Ports?
根据 Cockburn 的文章,它说
通常会有多个适配器用于任何一个端口,用于可能插入该端口的各种技术。
我想不出单个端口需要多个适配器的场景。你能给我一个场景,以便我可以充分利用架构。
这是我的观点:
是的,一个端口可以同时有流入和流出操作。对我来说,这取决于六边形实现的用例以及它使用该端口的原因。
例如我可以想到一个端口 "IPersistenceGateway",它具有像 "GetUsers" 和 "SaveUser" 这样的读写方法。该端口代表所有六边形的持久化抽象;在其他情况下,我可以将 "IReadingPersistenceGateway" 和 "IWritingPersistenceGateway" 上面提到的两个操作分开,以便将 reading/writing 操作“à la CQRS”分开。
我认为您的 "Application layers" 应该被考虑 "inside the hexagon":所以是的,消息处理程序可以注入端口依赖项。我认为消息处理程序应该是唯一从六边形外部可见的对象,因此是第一个获得端口的对象,由外部注入。
在我上面提到的示例中,端口是 "IPersistenceGateway",可能有一个 "MySqlPersisteceGateway" 和一个 "MongoPersistenceGateway" 来管理抽象的持久性需求六边形,用于 MySql 和 MongoDb 上下文。
就您的情况而言,据我了解,我认为 JMS 适配器可能已经注入了六边形的消息处理程序,因为 JMS 适配器必须 "push" 向六边形发送消息,而不是相反(从适配器中提取消息的 xexagon)。如果这是正确的,那么(在我看来)拥有一个直接引用六边形内的消息处理程序的适配器就没有问题。重点始终是依赖的方向:总是朝向抽象,从六边形的外部到内部(DIP,Dependency Inversion Principle)。
我阅读了有关 Alistair Cockburn 提出的端口和适配器架构的不同来源,发现它适合我开发网关服务应用程序的场景,该应用程序从多个源接收消息并处理消息并将消息发送到多个目的地。这是我的详细实现。
- 目前消息来源是单一的(JMS Queue)
- JMS 端口订阅 JMS 消息队列并将其传递给 JMS 适配器,后者又调用相应的消息处理程序。
- 消息处理程序依次调用业务域层,该层独立于消息的来源或目的地,如 cockburn 所提议的。
- 具有依赖注入容器注入的 JMS 端口、WCF 端口、DB 端口、TCP 端口的消息处理程序依次调用 JMS 端口、TCP 端口和 WCF 端口以 publish/send 域处理的消息。
如果我是否偏离了 Cockburn 提出的架构,我有几个关键questions/doubts。
- 单个端口能否同时处理 inflow/outflow 消息(在本例中为 JMS 端口)。还是为消息的流入和流出设置单独的端口是一个好习惯。
2.As 根据 cockburn 的文章
入站通信:"As events arrive from the outside world at a port, a technology-specific adapter converts it into a usable procedure call or message and passes it to the application."
出站通信:"When the application has something to send out, it sends it out through a port to an adapter, which creates the appropriate signals needed by the receiving technology (human or automated)."
所以我将处理后的消息直接传递到端口,该端口又调用适配器根据目标要求转换消息。
Message Handlers(Application Layer)是否可以依赖注入的Ports?
根据 Cockburn 的文章,它说
通常会有多个适配器用于任何一个端口,用于可能插入该端口的各种技术。
我想不出单个端口需要多个适配器的场景。你能给我一个场景,以便我可以充分利用架构。
这是我的观点:
是的,一个端口可以同时有流入和流出操作。对我来说,这取决于六边形实现的用例以及它使用该端口的原因。 例如我可以想到一个端口 "IPersistenceGateway",它具有像 "GetUsers" 和 "SaveUser" 这样的读写方法。该端口代表所有六边形的持久化抽象;在其他情况下,我可以将 "IReadingPersistenceGateway" 和 "IWritingPersistenceGateway" 上面提到的两个操作分开,以便将 reading/writing 操作“à la CQRS”分开。
我认为您的 "Application layers" 应该被考虑 "inside the hexagon":所以是的,消息处理程序可以注入端口依赖项。我认为消息处理程序应该是唯一从六边形外部可见的对象,因此是第一个获得端口的对象,由外部注入。
在我上面提到的示例中,端口是 "IPersistenceGateway",可能有一个 "MySqlPersisteceGateway" 和一个 "MongoPersistenceGateway" 来管理抽象的持久性需求六边形,用于 MySql 和 MongoDb 上下文。
就您的情况而言,据我了解,我认为 JMS 适配器可能已经注入了六边形的消息处理程序,因为 JMS 适配器必须 "push" 向六边形发送消息,而不是相反(从适配器中提取消息的 xexagon)。如果这是正确的,那么(在我看来)拥有一个直接引用六边形内的消息处理程序的适配器就没有问题。重点始终是依赖的方向:总是朝向抽象,从六边形的外部到内部(DIP,Dependency Inversion Principle)。