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

.NET 6源代码生成器:跨项目从实体类生成DTO可行吗?

解决方案:基于服务端实体在共享项目生成DTO

核心目标:在Project C(共享项目)中借助Project B(服务端)的实体类,通过源代码生成器生成共用DTO,同时严格保证Project A(客户端)不直接依赖Project B。

以下是可落地的实现方案:

1. 配置项目依赖规则

  • 让源代码生成器模块(可单独抽离为类库)仅在编译时引用Project B:目的是获取实体类的元数据,不会引入运行时依赖
  • Project C的最终输出(生成的DTO类)不包含任何对Project B的引用,仅保留纯POCO结构
  • Project A和Project B分别引用Project C,实现DTO的双向共用

2. 源代码生成器的具体实现步骤

步骤1:创建生成器项目

新建一个.NET类库项目(例如命名为EntityToDtoGenerator),添加Microsoft.CodeAnalysis.CSharp和Microsoft.CodeAnalysis.Analyzers的NuGet包,同时添加对Project B的项目引用。

步骤2:编写DTO生成逻辑

通过Roslyn API扫描Project B中的实体类(可通过自定义特性标记需要生成DTO的实体),自动生成对应DTO类并输出到Project C。核心代码示例:

[Generator]
public class EntityDtoGenerator : ISourceGenerator
{
    public void Initialize(GeneratorInitializationContext context) { }

    public void Execute(GeneratorExecutionContext context)
    {
        // 筛选标记了[GenerateDto]特性的实体类
        var targetEntities = context.Compilation.SyntaxTrees
            .SelectMany(tree => tree.GetRoot().DescendantNodes())
            .OfType<ClassDeclarationSyntax>()
            .Where(cls => cls.AttributeLists.Any(attr => 
                attr.Attributes.Any(a => a.Name.ToString() == "GenerateDto")));

        foreach (var entity in targetEntities)
        {
            // 提取实体的属性,生成DTO代码
            var propertyCode = string.Join("\n    ", 
                entity.Members.OfType<PropertyDeclarationSyntax>()
                    .Where(p => !p.AttributeLists.Any(attr => attr.Attributes.Any(a => a.Name.ToString() == "IgnoreDto")))
                    .Select(p => $"public {p.Type} {p.Identifier} {{ get; set; }}"));

            var dtoSource = $@"
namespace SharedProject.Dtos;

public class {entity.Identifier.Text}Dto
{{
    {propertyCode}
}}";
            // 将生成的代码添加到Project C的编译输出
            context.AddSource($"{entity.Identifier.Text}Dto.g.cs", dtoSource);
        }
    }
}

步骤3:关联生成器到Project C

在Project C的项目文件中添加生成器引用,配置为编译时依赖:

<ItemGroup>
    <ProjectReference Include="..\EntityToDtoGenerator\EntityToDtoGenerator.csproj" 
                      OutputItemType="Analyzer" 
                      ReferenceOutputAssembly="false" />
</ItemGroup>

3. 关键注意事项

  • 隔离运行时依赖:确保生成的DTO类不包含任何EF特有的属性或引用,只保留需要暴露给客户端的字段
  • 精准筛选实体:给Project B中需要生成DTO的实体标记自定义特性(如[GenerateDto]),同时用[IgnoreDto]标记不需要暴露的属性
  • 避免导航属性泄露:生成器要过滤掉EF实体中的导航属性,防止客户端获取不必要的关联数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:05:21