You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CLEAN架构下如何将请求契约对象传递至应用层?

问题:符合CLEAN架构的请求对象传递方案

按照CLEAN架构设计规则,API/Web/Presentation层不得引用Domain层,Application层不得引用Contracts层。当前控制器Action接收一个冗长的契约请求对象Root,希望将整个对象传递给应用层的_processEntityService服务,而非逐个传递属性(当前代码为逐个传参的方式),该如何实现?

当前代码示例

[HttpPost("process")]
public IActionResult Process(Root entityInput)
{
    //_processEntityService 位于应用层项目中
    //我希望直接传递整个Root对象给服务,而非像下面这样逐个传参
    var result = _processEntityService.ProcessEntity(
        entityInput.Companies.First().CompanyMainName.Name
        ,entityInput.Companies.First().CompanyType);
    return Ok(result);
}

解决方案

要满足CLEAN架构的依赖规则,同时实现传递整个请求对象的需求,可以采用以下两种核心方案:

1. 应用层定义专属DTO,做请求对象映射

  • 在应用层项目中,定义与Contracts层Root结构完全匹配的ProcessEntityRequestDto(包含所有需要的嵌套对象和属性)
  • 在API层(Presentation层)中,将接收到的Contracts层Root对象,手动或通过映射工具转换为应用层的ProcessEntityRequestDto,再传递给服务
  • 这种方式严格遵守CLEAN架构的依赖边界,避免应用层直接依赖Contracts层

代码调整示例

应用层定义DTO

public class ProcessEntityRequestDto
{
    public List<CompanyDto> Companies { get; set; }
    // 其他必要属性...
}

public class CompanyDto
{
    public CompanyMainNameDto CompanyMainName { get; set; }
    public string CompanyType { get; set; }
}

public class CompanyMainNameDto
{
    public string Name { get; set; }
}

API层控制器修改

[HttpPost("process")]
public IActionResult Process(Root entityInput)
{
    // 手动映射(或用AutoMapper简化)
    var requestDto = new ProcessEntityRequestDto
    {
        Companies = entityInput.Companies.Select(c => new CompanyDto
        {
            CompanyMainName = new CompanyMainNameDto { Name = c.CompanyMainName.Name },
            CompanyType = c.CompanyType
        }).ToList()
    };

    var result = _processEntityService.ProcessEntity(requestDto);
    return Ok(result);
}

应用层服务方法修改

public Result ProcessEntity(ProcessEntityRequestDto request)
{
    // 直接使用DTO对象的属性,无需逐个传参
    var targetCompany = request.Companies.First();
    var companyName = targetCompany.CompanyMainName.Name;
    var companyType = targetCompany.CompanyType;
    
    // ...业务逻辑实现
    return new Result();
}

2. 引入独立共享DTO层(跨层中立契约)

  • 创建一个独立的类库(如Shared.Dtos),专门存放跨层传输的数据结构,让Presentation层和Application层都引用这个类库
  • 将原Contracts层的Root迁移到共享DTO层,或者在共享层定义与Root结构一致的ProcessEntityRequest对象
  • API层直接接收共享层的ProcessEntityRequest对象,无需转换即可传递给应用层服务
  • 这种方式通过依赖反转,避免了层与层之间的直接耦合,符合CLEAN架构原则

核心逻辑说明

  • 共享DTO层仅包含纯数据结构,无业务逻辑,作为Presentation层和Application层之间的中立传输契约
  • API层控制器参数改为ProcessEntityRequest(来自共享层),直接传递给应用层服务
  • 应用层服务方法接收ProcessEntityRequest对象,直接使用其属性完成业务处理

关键注意事项

  • 无论采用哪种方案,必须保证Application层不直接依赖Contracts层,Presentation层不依赖Domain层
  • 映射过程要确保所有必要字段都被正确转换,避免数据丢失
  • 若使用AutoMapper等工具,映射配置需放在Presentation层,不要让应用层依赖映射工具

内容的提问来源于stack exchange,提问作者Tejas Vaishnav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 22:57:32