哪些类型的代码适合服务层?

发布于 2024-11-16 17:40:42 字数 780 浏览 4 评论 0原文

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

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


存储库协调?

它看起来像实体不应引用存储库,因此服务层中是否应该存在加载/保存/逐出实体的调用?

涉及存储库的业务逻辑?

如果上述情况成立,是否应该在服务层中执行类似检查用户名是否不同的操作(即调用 GetUsersByUsername 并检查结果)?在建议数据库应该处理不同的数据之前,先验证一下密码是否在 90 天内没有被使用过?

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

我对此不太确定,但假设您需要对一组可能会也可能不会的实体应用操作是相关的,并不真正适用于单个实体。实体是否应该能够对这些集合进行操作,或者此类事物是否属于服务层?

映射?

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


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

Assume you have entities, a service layer, and repositories (with an ORM like NHibernate). The UIs interact with the service layer.

What types of code are appropriate for the service layer?


Repository Coordination?

It looks like entities should not reference the repository so should calls for loading/saving/evicting entities exist in the service layer?

Business Logic that Involves Repositories?

If the above is true, should something like checking if a username is distinct go in the service layer (i.e. call GetUsersByUsername and check the results)? Before suggesting that the DB should handle distinct, what about verifying that a password hasn't been used in 90 days?

Business Logic that Involves Multiple Entities?

I'm not sure about this one, but say you have the need to apply an operation against a collection of entities that may or may not be related and is not really applicable to a single entity. Should entities be capable of operating on these collections or does this sort of thing belong in the service layer?

Mapping?

Whether you use DTOs or send your entities to/from your service layer, you will likely end up mapping (preferably with AutoMapper). Does this belong in the service layer?


I'm looking for confirmation (or rejection) of the ideas listed above as well as any other thoughts about the responsibilities of a service layer when working with entities/repositories.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

静谧幽蓝 2024-11-23 17:40:42

存储库协调?

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


涉及存储库的业务逻辑?

是的,检查用户名是否不同可能存在于服务层。因为用户通常是一个聚合根,并且聚合根存在于全局上下文中(没有任何东西“保存”它们)。我个人把这种逻辑放在存储库中或者直接通过 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)); //<--
  }
}

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

例如,这很糟糕:

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

而是使用:

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

映射?

我想映射到 dto 的活动位于服务层。我的映射类位于 Web 项目中的视图模型类旁边。

Repository Coordination?

Aggregate roots should draw transactional boundaries. Therefore - multiple repositories should rarely be involved. If they are - that usually happens when You are creating new aggregate root (as opposed to modifying its state).


Business Logic that Involves Repositories?

Yes, checking if username is distinct might live in service layer. Because User usually is an aggregate root and aggregate roots live in global context (there is nothing that "holds" them). I personally put that kind of logic in repository or just check directly through ORM.

As for checking password usage - that's a concern of user itself and should live underneath User object. Something like this:

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

Business Logic that Involves Multiple Entities?

Aggregate root should manage their entity collections.

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

But remember that aggregate root should not micro-control its entities.

E.g. this is bad:

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

Instead use:

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

Mapping?

I suppose mapping to dto`s live in service layer. My mapping classes lives next to view model classes in web project.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文