什么类型的代码适合服务层?

时间:2011-06-23 13:51:50

标签: domain-driven-design repository soa business-logic

假设您有实体,服务层和存储库(使用像NHibernate这样的ORM)。 UI与服务层交互。

什么类型的代码适合服务层?


存储库协调?

看起来像entities should not reference the repository所以服务层中是否应该存在加载/保存/逐出实体的调用?

涉及存储库的业务逻辑?

如果上述情况属实,那么检查用户名是否不同就应该进入服务层(即调用GetUsersByUsername并检查结果)?在建议数据库应该处理不同之前,如何验证密码是否在90天内未被使用?

涉及多个实体的业务逻辑?

我不确定这个,但是说​​你需要针对可能相关或不相关的实体集合应用操作,并且不适用于单个实体。实体应该能够对这些集合进行操作还是属于服务层?

映射

无论您是使用DTO还是将服务层发送到服务层,您都可能最终映射(最好使用AutoMapper)。这属于服务层吗?


我正在寻找对上面列出的想法的确认(或拒绝),以及在使用实体/存储库时对服务层职责的任何其他想法。

1 个答案:

答案 0 :(得分:2)

  

存储库协调?

聚合根应该绘制事务边界。因此 - 很少涉及多个存储库。如果它们 - 通常在您创建新聚合根目录时发生(而不是修改其状态)。


  

涉及存储库的业务逻辑?

是的,检查用户名是否不同可能存在于服务层中。因为用户通常是聚合根,并且聚合根存在于全局上下文中(没有“持有”它们)。我个人将这种逻辑放在存储库中或直接通过ORM检查。

至于检查密码使用情况 - 这是用户自身的顾虑,应该存在于User对象下面。像这样:

class User{
  void Login(){
    LoggedOn=DateTime.Now;
    ...
  }
  bool HasLoggedInLast90Days(){
    return (DateTime.Now-LoggedOn).Days<=90;
  }
}

  

涉及多个实体的业务逻辑?

聚合根应管理其实体集合。

class Customer{
  void OrderProduct(Product product){
    Orders.Add(new Order(product)); //<--
  }
}

但请记住,聚合根不应微观控制其实体。

E.g。这很糟糕:

class Customer{
  void IsOrderOverdue(Order order){
    return Orders.First(o=>o==order)....==...;
  }
}

改为使用:

class Order{
  void IsOverdue(){
    return ...;
  }
}

  

映射?

我想映射到dto的live in service层。我的映射类位于Web项目中的视图模型类旁边。