c# - 创建DTO时如何避免冗余的业务逻辑(DB fetching)?

标签 c# architecture n-tier-architecture design-principles

我正在用 C# 开发 N 层应用程序。服务器端由以下几层组成:

  • 数据访问层(EF Code First 实体和 DbContext)
  • 业务层(包含所有业务逻辑和对象)
  • WCF 服务层(每次调用实例化服务,公开业务层的一些操作)

现在客户端请求是这样处理的:

  1. 客户端创建Request DTO并将其发送到服务层
  2. 服务层将此 DTO 映射到业务对象并调用 BL 方法
  3. 业务层执行一些有用的操作,向 DAL 发出请求,然后将一些业务对象返回给服务
  4. 服务层将业务对象映射到DTO Response并返回给客户端

尽管 Automapper 减少了代码重复,但它仍然可以很好地工作。实际问题是这样的:

客户端在不同的 View 中显示相同的对象:网格、表单等。例如,网格(列表) View 仅需要用户对象中的 Id 和名称,而表单(详细信息) View 需要每个用户的属性。但业务层对 View 一无所知。它只能向服务调用提供完整的 UserBL 对象,然后服务负责将此 UserBL 映射到 UserListDto 或 UserDetailsDto。对于一些重对象,从数据库中获取额外的字段会成为性能问题。

那么,业务层是否应该为不同的客户端操作提供不同的方法呢?我不喜欢这个解决方案,因为它看起来像是领域逻辑污染,但我不知道还能做什么。

最佳答案

Client shows same objects in different views: grid, form, etc. For example, grid(list) view requires only Id and Name from User object, while Form(details) view needs every User's property. But Business layer knows nothing about views. It can only provide full UserBL object to Service calls and then it's the Service responsibility to map this UserBL to UserListDto or UserDetailsDto. And for some heavy objects, fetching extra fields from DB become a performance issue.

我通常会根据 BL 中执行的操作类型返回业务实体的不同表示。例如,在搜索时返回用户的搜索表示,其中仅包含身份用户所需的最小属性集。当获取特定用户时,我返回一个完整的业务对象。

关于您的代码重复问题。这不是重复。用户的不同表现形式具有不同的职责。

  • DTO:负责转移用户并在业务层和消费者之间创建松耦合
  • BO:负责封装和执行业务操作
  • DB实体:负责使BO对象持久化

因此,如果您仅使用用户的一种表示形式,那么您将合并所有这些职责,因此必须在良好的设计中做出牺牲才能让每个人都能使用它。唯一真正的好处是您必须少写几行代码。当您开始维护已发布的应用程序时,请记住这一点。您节省了几行代码,但维护起来却变得更加困难。

关于c# - 创建DTO时如何避免冗余的业务逻辑(DB fetching)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34299456/

相关文章:

asp.net-mvc - 如何使用 EF 构建 ASP.Net MVC 应用程序?

database-design - 减少数据库设计中的重复信息

unit-testing - 在不使用 IoC 容器的情况下,是否可以在 3 层或 n 层架构中测试洋葱式代码?

c# - Linq 和 Dictionary 以及转换数组值

c# - 如何从负载均衡器后面获取客户端的 IP 地址?

javascript - 仅从内容页刷新母版页

c# - 如何在 C# 中使用 1 Console.Writeline() 编写两个字符串及其两个变量值

kubernetes - Kubernetes 上的 Redis 主/从复制可实现超低延迟

validation - 验证应该针对业务模型还是 View 模型?

java - 如何在 3 层架构中组织依赖关系