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

电商项目整洁架构下,如何避免重复模型并遵循DRY原则与依赖规则?

四层整洁架构+CQRS下模型重复问题的解决方案

一、代码生成工具自动生成模型与映射

  • 基于T4模板、Roslyn或代码生成框架,定义包含共用属性和各层特有属性的模板,一键生成领域Entity、应用层命令/查询、UI层VM文件,以及对应的映射配置。
  • 示例:针对Option系列模型,在模板中配置Name、Value等共用属性,再分别为领域层添加Id、CreatedAt,UI层添加IsSelected,应用层添加OperationType,执行模板即可生成所有重复代码。

二、用共享契约接口减少重复定义

  • 在独立的契约项目中定义包含共用属性的接口(符合整洁架构“所有层依赖抽象”的规则),各层模型实现该接口并仅补充自身特有属性。
  • 代码示例:
    // 契约层接口
    public interface IOptionCore
    {
        string Name { get; set; }
        string Value { get; set; }
        int SortOrder { get; set; }
    }
    
    // 领域层实体
    public class OptionDetail : IOptionCore, IEntity
    {
        public Guid Id { get; set; }
        public DateTime CreatedAt { get; set; }
        // 实现接口共用属性
        public string Name { get; set; }
        public string Value { get; set; }
        public int SortOrder { get; set; }
    }
    
    // UI层视图模型
    public class OptionVM : IOptionCore
    {
        public bool IsSelected { get; set; }
        // 实现接口共用属性
        public string Name { get; set; }
        public string Value { get; set; }
        public int SortOrder { get; set; }
    }
    
  • 映射工具(如AutoMapper)可基于接口自动匹配属性,无需手动编写大量映射规则。

三、优化CQRS模型结构,复用基础模型

  • 对业务逻辑相似的命令/查询,定义基础父类,具体命令/查询继承父类以复用属性。
  • 代码示例:
    // 应用层基础命令
    public abstract class OptionCommandBase
    {
        public string Name { get; set; }
        public string Value { get; set; }
        public int SortOrder { get; set; }
    }
    
    public class CreateOptionCommand : OptionCommandBase, IRequest<Guid>
    {
        // 无额外属性,直接继承
    }
    
    public class UpdateOptionCommand : OptionCommandBase, IRequest<bool>
    {
        public Guid Id { get; set; }
    }
    

四、利用映射工具的自动映射能力

  • 配置AutoMapper/Mapster等工具的全局映射规则,基于约定自动匹配同名属性。对于实现同一契约接口的模型,可直接配置接口间的映射,所有实现类自动继承该规则。
  • 代码示例(AutoMapper):
    public class MappingProfile : Profile
    {
        public MappingProfile()
        {
            CreateMap<IOptionCore, IOptionCore>(); // 接口间基础映射
            CreateMap<OptionDetail, AppOption>().ReverseMap();
            CreateMap<AppOption, OptionVM>().ReverseMap();
        }
    }
    

五、谨慎放宽架构边界,复用基础DTO

  • 对于无业务逻辑的纯数据载体模型,可将其放在抽象契约层,允许各层直接使用,仅在需要扩展时创建子类。比如定义OptionBase在契约层,领域层OptionDetail继承并添加领域属性,UI层OptionVM继承并添加UI属性。
  • 注意:必须保证这些基础模型无状态、无业务逻辑,避免破坏架构的独立性和可测试性。

内容的提问来源于stack exchange,提问作者sarang lad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 03:24:57