.NET - 使用集成事件在模块之间传递对象

.NET - Passing objects between modules using integration events

提问人:Mateusz Babski 提问时间:7/23/2023 更新时间:7/23/2023 访问量:79

问:

我正在研究使用 DDD 方法的模块化单体应用程序。我已经将购物篮和订单模块分开了。我已经决定要使用事件在模块之间进行通信,在它们之间保持松散耦合并尽可能独立。我正在使用中介来发布事件。

在篮子模块中,我有CheckoutCommand,它最终发布事件BasketCheckedOutEvent。

public async Task<Unit> Handle(CheckoutBasketCommand command, CancellationToken cancellationToken)
    {
        var customerId = _currentUserService.UserId;
        var basket = await _basketRepository.GetBasketByCustomerId(customerId)
            ?? throw new NotFoundException("Basket not found.");

        await _unitOfWork.CommitAndDispatchDomainEventsAsync(basket);
        await _eventDispatcher.PublishAsync(new BasketCheckedOutEvent(basket,
                                                                      command.CouponCode,
                                                                      command.ShippingMethod,
                                                                      command.PaymentMethod));

        
    }

事件

public record BasketCheckedOutEvent(Basket Basket,
                                    string CouponCode,
                                    int ShippingMethod,
                                    int PaymentMethod) : IEvent
{
}

我希望其他模块处理此事件,但存在问题。另一个模块无权访问 Basket 对象(因为它是不同模块中的域对象 - 合理)。所以我无法创建具有篮子传递事件的订单。

我正在努力为此找到解决方案。我唯一想到的是将 BasketCheckedOutEvent 放入 Shared.Application 模块,然后创建一个 BasketDto - 然后 Dto 和 Event 将在 Order 模块中可用,我可以进一步处理它。在我看来,这看起来不是一个好的做法。它为 fe 中非常简单的东西创造了另一层抽象。经典的单体。

只传篮筐。Id 没问题(以最小化事件大小),但随后我必须以某种方式从我无法访问的另一个模块中的存储库中读取篮子。

谢谢!

C# .NET 事件处理 域驱动设计

评论

0赞 Fildor 7/23/2023
传递一个呢?然后,每个模块都可以有自己的篮子表示形式。IBasket

答:

0赞 mtkachenko 7/23/2023 #1

我想说的是,传球是可以的。事件生产者和事件订阅者这两个模块都应该有自己的存储库接口,以便能够从数据库中获取篮子详细信息。我建议你查看 MODULAR MONOLITH: A PRIMER 文章和相关的 github 存储库basket.Id

评论

0赞 Mateusz Babski 7/23/2023
这个 repo 和博客是我好几个星期的圣经:D但我在想,在另一个模块中显示篮子存储库是否是一种很好的做法。更重要的是,我在域层中有存储库接口,可以将与域相关的文件/逻辑保持在一起
0赞 mtkachenko 7/23/2023
在这里,我们可以讨论您的分离是否正确,即在单独的模块中具有篮子和顺序。但总的来说 - 是的,这样做是可以的。这就像在微服务中使用 GET http 方法一样。在 github 存储库中,您可以找到两个模块具有重复的 db repo 接口的情况。它类似于微服务的客户端库。