如何在C#不同程序集中映射类,无需逐个继承实体?
C#原生方式实现跨程序集类映射的简化方案
问题描述
是否存在C#原生方式,通过适配器(媒介)实现不同程序集间的类映射?当前采用逐个继承领域实体的方式,当领域程序集有40个实体时,需在应用程序集中创建40个独立继承文件或一个包含所有继承类的文件,再在基础设施程序集中使用这些映射类。这种操作重复繁琐且代码冗余,希望找到简化方案,优先使用C#内置方法而非外部库。
现有实现方式
领域程序集(Domain)
SiteEntity.cs
namespace Domain.Entities; public class SiteEntity { public string Name { get; set; } public string Url { get; set; } } public class UserEntity {}
应用程序集(Application)
方式1:单个实体对应单个文件(MapSiteEntity.cs)
using Domain.Entities; namespace Application.Entities; public class MapSiteEntity : SiteEntity {}
方式2:单个文件包含所有映射类(MapEntities.cs)
using Domain.Entities; namespace Application.Entities; public class MapSiteEntity : SiteEntity {} public class MapUserEntity : UserEntity {}
基础设施程序集(Infrastructure)
ApplicationDbContext.cs
using Application.Entities; DbSet<MapSiteEntity> Sites => Set<MapSiteEntity>();
期望目标
创建单个文件(如MapperEntity.cs),自动将领域程序集Entities文件夹下的所有类型转换为映射类。
简化方案:使用T4文本模板(C#原生支持)
T4是Visual Studio内置的代码生成工具,能在编译时自动生成映射类,完全符合原生要求,无需外部库。
步骤1:创建T4模板文件
在应用程序集中添加名为MapEntities.tt的T4模板文件,内容如下:
<#@ template debug="false" hostspecific="true" language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Reflection" #> <#@ import namespace="System.IO" #> <#@ output extension=".cs" #> using Domain.Entities; namespace Application.Entities { <# // 调整为你的领域程序集实际输出路径 string domainAssemblyPath = Path.Combine(Host.ResolvePath(".."), "Domain", "bin", "Debug", "net8.0", "Domain.dll"); Assembly domainAssembly = Assembly.LoadFrom(domainAssemblyPath); // 筛选Domain.Entities下的非抽象、非静态类 var entityTypes = domainAssembly.GetTypes() .Where(t => t.Namespace == "Domain.Entities" && !t.IsAbstract && !t.IsStatic && t.IsClass); foreach (var type in entityTypes) { string mapClassName = $"Map{type.Name}"; #> public class <#= mapClassName #> : <#= type.Name #> {} <# } #> }
步骤2:配置程序集路径
修改domainAssemblyPath为你的领域程序集实际编译输出路径,确保模板能加载最新的领域实体类型。
步骤3:自动生成代码
保存模板后,Visual Studio会自动生成对应的MapEntities.cs文件,包含所有领域实体的映射类。后续领域实体新增/修改时,右键模板选择「运行自定义工具」即可更新生成代码。
可选进阶方案:编译时代码生成器(Source Generator)
若需要完全自动化的编译时生成,可使用C#原生的Source Generator。它能在编译过程中动态扫描领域程序集并生成映射类,无需手动运行工具,但实现复杂度略高于T4,适合大规模项目场景。
内容的提问来源于stack exchange,提问作者Dotnet
相关产品推荐
相关产品推荐

