如何使用CodegenCS从Code-First实体类生成视图模型?
使用CodegenCS基于Code-First实体类生成视图模型的解决方案
引用外部实体类的实现方式
完全可以引用模板外的实体类,CodegenCS模板本质是可执行的C#脚本,步骤如下:
- 引用实体类所在项目的编译DLL:在模板顶部添加
#r "../bin/Debug/net7.0/YourClassLibrary.dll"(替换为你的类库实际路径,同一解决方案下可直接引用项目名称) - 引入实体类命名空间:添加
using YourNamespace.Entities; - 通过反射获取所有实体类:筛选程序集中符合条件的类(比如特定命名空间、带有
Entity特性的类)
示例代码片段:
#r "../bin/Debug/net7.0/YourClassLibrary.dll" using YourNamespace.Entities; using System.Reflection; // 获取目标命名空间下的所有实体类 var entityTypes = Assembly.LoadFrom("../bin/Debug/net7.0/YourClassLibrary.dll") .GetTypes() .Where(t => t.IsClass && !t.IsAbstract && t.Namespace == "YourNamespace.Entities");
单模板生成多输出的简化实现
CodegenCS原生支持单模板生成多个文件,比T4操作简单,核心是用*CodegenContext.AddFile*方法为每个实体创建独立输出文件:
foreach (var entityType in entityTypes) { var vmClassName = $"{entityType.Name}ViewModel"; var writer = new CodegenTextWriter(); // 生成ViewModel的命名空间和类结构 writer.WriteLine($"namespace YourNamespace.ViewModels;"); writer.WriteLine(); writer.WriteLine($"public class {vmClassName}"); writer.WriteLine("{"); writer.Indent(); // 遍历实体属性生成对应的ViewModel属性 foreach (var prop in entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { writer.WriteLine($"public {prop.PropertyType.Name} {prop.Name} {{ get; set; }}"); } writer.Unindent(); writer.WriteLine("}"); // 将生成的代码写入指定文件 Context.AddFile($"{vmClassName}.cs", writer.ToString()); }
扩展更多代码生成场景
基于上述能力,你可以轻松扩展其他代码生成需求:
- 生成带有验证特性的ViewModel
- 生成CRUD控制器基础代码
- 生成数据传输对象(DTO)
- 生成仓储层(Repository)接口与实现
- 基于自定义特性生成特定业务逻辑代码
注意事项
- 确保实体类项目已编译,否则模板无法加载对应的DLL
- 可通过条件编译指令切换Debug/Release环境的DLL路径,比如:
#if DEBUG #r "../bin/Debug/net7.0/YourClassLibrary.dll" #else #r "../bin/Release/net7.0/YourClassLibrary.dll" #endif
- 反射筛选时注意排除抽象类、系统类等非目标实体类
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

