2012-05-24 65 views
2

我正在努力锻炼坚持我的域更改的最佳位置。我有以下实体:DDD Enity持久性场景

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具有依赖性。

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

有什么想法? 谢谢

回答

3

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

+0

谢谢你,这是有道理的。我感到困惑。我设想ddd域名服务就像创建api一样,这样您就可以对域对象方法进行单个调用来执行交互。有点像asp.net成员资格类为用户对象user.changepassword工作。我现在已经意识到,该功能应该在ddd的应用程序层。 – Mantisimo

3

正如杰克休斯所说,实体不应该依赖他们的存储库。另外,我不明白为什么你需要一个'服务'来获得你的贸易实体?这是存储库的责任。也不知道为什么你会将交易对象的引用传递给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); 
     } 
    } 
+0

是啊,你是对的...抱歉,忽略那部分。这是匆忙写的。 Tradeservice.get()应该是一个仓库,并且贸易参考应该是一个指导。我会修改这个......感谢您对如何编写它的建议。这看起来很干净! – Mantisimo

+0

嗨,我可以问你在上面的代码中如何使用unitOfWork工厂。不应该将单元工作注入到_tradeRepository构造函数中吗?我不知道它在上面如何使用?谢谢 – Mantisimo

+0

将它传递给存储库是一种方法。当UoW被设置在当前线程中时,我倾向于以被动方式使用它,所以它可用于当前上下文中的存储库。类似于Thread.CurrentPrincipal,执行操作的当前用户始终可用。 –