【问题标题】:What types of code are appropriate for the service layer?什么类型的代码适合服务层?
【发布时间】:2011-09-21 06:13:32
【问题描述】:

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

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


存储库协调?

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

涉及存储库的业务逻辑?

如果上述情况属实,是否应该在服务层中检查用户名是否不同(即调用 GetUsersByUsername 并检查结果)?在建议 DB 应该处理 distinct 之前,验证一个密码是否在 90 天内未被使用?

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

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

映射?

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


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

【问题讨论】:

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


    【解决方案1】:

    存储库协调?

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


    涉及存储库的业务逻辑?

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

    至于检查密码的使用 - 这是用户本身的问题,应该存在于用户对象之下。像这样的:

    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)); //<--
      }
    }
    

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

    例如这很糟糕:

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

    改为使用:

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

    映射?

    我想映射到 dto 的实时服务层。我的映射类位于 web 项目中的视图模型类旁边。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-20
      • 1970-01-01
      • 1970-01-01
      • 2017-09-25
      • 2011-07-21
      • 2017-07-02
      • 1970-01-01
      • 2011-03-10
      相关资源
      最近更新 更多