如何在创建DTO时避免冗余业务逻辑(数据库提取)?

时间:2015-12-15 21:10:58

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

我在C#中开发N-Tier应用程序。服务器端包含以下层:

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

现在以这种方式处理客户端请求:

  1. 客户创建请求DTO并将其发送到服务层
  2. 服务层将此DTO映射到业务对象并调用BL方法
  3. 业务层执行一些有用的操作,向DAL发出请求,然后将一些业务对象返回到服务
  4. 服务层将业务对象映射到DTO响应并返回客户端
  5. 尽管Automapper减轻了代码重复,但它仍然很好用。实际问题是:

    客户端在不同视图中显示相同的对象:网格,表单等。例如,网格(列表)视图仅需要来自User对象的Id和Name,而Form(详细信息)视图需要每个User的属性。但是Business层对视图一无所知。它只能为Service调用提供完整的UserBL对象,然后将UserBL映射到UserListDto或UserDetailsDto是服务职责。对于一些重型对象,从DB中获取额外的字段会成为性能问题。

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

1 个答案:

答案 0 :(得分:2)

  

客户端在不同视图中显示相同的对象:网格,表单等。例如,网格(列表)视图仅需要来自User对象的Id和Name,而Form(详细信息)视图需要每个User的属性。但是Business层对视图一无所知。它只能为Service调用提供完整的UserBL对象,然后将UserBL映射到UserListDto或UserDetailsDto是服务职责。对于一些重型对象,从DB中获取额外的字段会成为性能问题。

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

关于代码重复的问题。这不是重复。用户的这些不同表示具有不同的职责

  • DTO:负责转移用户并在业务层和消费者之间创建松耦合
  • BO:负责封装和执行业务运营
  • 数据库实体:负责使BO对象持久无知

因此,如果您只使用一个用户的表示,您将合并所有这些责任,因此必须在良好的设计中做出牺牲才能够将其用于每个人。唯一真正的好处是你必须写几行代码。当您开始维护已发布的应用程序时,请记住这一点。你节省了几行,但要维护的应用程序要难得多。