【问题标题】:DDD Enity persistance scenarioDDD 实体持久化场景
【发布时间】:2023-03-27 07:00:01
【问题描述】:

我正在努力寻找最好的地方来保持我的域更改。我有以下实体:

public class Period
{
   public Guid PeriodId { get; set; }
   public DateTime StartDate { get; set; }
   public DateTime EndDate { get; set; }
}

Trade
{
   public Guid TradeId { get; set; }
   Trader Instigator { get; set; }
   Trader Acceptor { get; set; }
   Period period { get; set; }
   public long Volume { get; set; }
   public decimal Price { get; set; }
}

现在为了创建新交易,我已将其卸载到域服务

tradeService.PlaceTrade(Guid periodId, Guid UserId, decimal price. long volume)

地方交易功能似乎很适合上述域服务,交易服务坚持交易。我传入了一个 ITradeRepository 类以方便使用。

为了接受交易,我想要以下内容,以便交易的域逻辑位于交易实体内。

Trade trade = tradeRepository.Get(Guid tradeId)

TradeStatus = trade.Accept(userId);

上述问题在于 Trade 实体负责保存数据,因此依赖于 ITradeRepository。

这是正确的做法吗?感觉很脏?或者更好的方法是为交易类创建一个扩展方法以促进接受交易的相同功能?

有什么想法吗? 谢谢

【问题讨论】:

    标签: c# domain-driven-design


    【解决方案1】:

    正如 Jack Hughes 所说,实体不应依赖于其存储库。另外,我不明白您为什么需要“服务”来获得您的贸易实体?这是存储库的责任。也不确定为什么要将交易对象的引用传递给 get 方法?

    这就是我的编码方式:

       //This is an application service method    
        public void AcceptTrade(Guid tradeId, Guid acceptingTraderId)
        {
            using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
            {
                Trade trade = _tradeRepository.GetById(tradeId);
                Trader acceptingTrader = _traderRepository.GetById(acceptingTraderId);
    
                trade.Accept(acceptingTrader);
    
                _tradeRepository.Save(trade);
            }
        }
    

    【讨论】:

    • 是的,你是对的……抱歉,忽略了那部分。写的很仓促。 Tradeservice.get() 应该是一个存储库,并且交易参考应该是一个指南。我会修改这个...感谢您对如何编写它的建议。看起来很干净!
    • 您好,请问在上面代码的上下文中,unitOfWork 工厂是如何使用的。不应该将 unitofwork 注入到 _tradeRepository 构造函数中吗?我不明白它在上面是如何使用的?谢谢
    • 将它传递到存储库是一种方法。我倾向于以被动方式使用它,在当前线程上设置 UoW,因此它可用于当前上下文中的存储库。与此类似,当前执行操作的用户所在的 Thread.CurrentPrincipal 始终可用。
    【解决方案2】:

    实体不应该对存储库有任何了解。因此,交易应该接受用户 ID 并设置其内部状态以反映它。但随后服务或控制器应将交易添加或保存到存储库。将交易保存到存储库,然后一次性持久化实体(可能还有许多交易聚合的子实体)。

    【讨论】:

    • 谢谢,这很有道理。我把事情弄糊涂了。我设想 ddd 域服务,例如创建一个 api,以便您可以对域对象方法进行一次调用以执行交互。有点像 asp.net 成员资格类如何为用户对象 user.changepassword 工作。我现在意识到该功能应该在 ddd 的应用程序层中。
    猜你喜欢
    • 2014-02-10
    • 2020-05-18
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 2015-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多