作为一名长期奋战在.NET开发一线的程序员,我深知那些重复性样板代码带来的痛苦。每次新建一个服务类,都要写一堆依赖注入的构造函数;每个实体类都要配套创建DTO、VO、Builder等各种衍生类。这些代码不仅编写耗时,维护起来更是噩梦。直到我遇到了Mud代码生成器,它彻底改变了我的开发方式。
Mud代码生成器是一套基于Roslyn的源代码生成器,专为.NET平台设计。它通过编译时代码生成技术,自动完成那些枯燥的样板代码编写工作。与Java生态中著名的Lombok类似,但功能更加丰富,特别适合现代.NET应用开发场景。下面我将详细介绍它的核心功能和使用技巧。
在.NET的依赖注入系统中,构造函数注入是最推荐的方式。但当一个服务需要注入多个依赖时,手动编写这些代码相当繁琐。Mud的ServiceCodeGenerator提供了多种注入特性,可以大幅简化这一过程。
最常用的是[ConstructorInject]特性,它会自动为标记的私有只读字段生成构造函数注入代码:
csharp复制[ConstructorInject]
public partial class OrderService
{
private readonly IOrderRepository _orderRepository;
private readonly IPaymentService _paymentService;
// 自动生成:
// public OrderService(IOrderRepository orderRepository, IPaymentService paymentService)
// {
// _orderRepository = orderRepository;
// _paymentService = paymentService;
// }
}
日志是每个服务都需要的功能,[LoggerInject]特性可以自动注入ILogger:
csharp复制[LoggerInject]
public partial class UserService
{
// 自动生成:
// private readonly ILogger<UserService> _logger;
// public UserService(ILoggerFactory loggerFactory)
// {
// _logger = loggerFactory.CreateLogger<UserService>();
// }
}
实际项目中,我们经常需要组合多种注入。Mud支持特性叠加使用:
csharp复制[ConstructorInject]
[LoggerInject]
[CacheInject]
public partial class ProductService
{
private readonly IProductRepository _productRepo;
// 自动生成包含所有依赖的构造函数
}
提示:注入顺序不影响最终生成的代码顺序,生成器会智能排序
Builder模式是创建复杂对象的好方法,但手动实现Builder类很麻烦。Mud的[Builder]特性可以自动生成完整的Builder类:
csharp复制[Builder]
public partial class ProductEntity
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
// 自动生成的Builder类
public class ProductEntityBuilder
{
private ProductEntity _entity = new ProductEntity();
public ProductEntityBuilder SetName(string name)
{
_entity.Name = name;
return this;
}
// 其他属性的Set方法...
public ProductEntity Build()
{
return _entity;
}
}
使用示例:
csharp复制var product = new ProductEntityBuilder()
.SetName("笔记本电脑")
.SetPrice(5999)
.Build();
现代Web开发中,我们通常不会直接暴露实体类,而是使用DTO进行数据传输。Mud的[DtoGenerator]特性可以自动生成各种DTO:
csharp复制[DtoGenerator]
public class UserEntity
{
public int Id { get; set; }
public string Username { get; set; }
public string Password { get; set; } // 敏感字段
}
// 自动生成以下类:
// 1. UserListOutput - 用于列表展示
// 2. UserCreateInput - 用于创建输入
// 3. UserUpdateInput - 用于更新输入
// 4. UserQueryInput - 用于查询过滤
生成的DTO会自动排除敏感字段(如密码),并包含适当的验证特性。
有时自动生成的映射逻辑需要定制。Mud允许通过partial方法进行扩展:
csharp复制[DtoGenerator]
public partial class OrderEntity
{
public decimal TotalAmount { get; set; }
// 自定义映射逻辑
partial void CustomMapping(OrderListOutput output)
{
output.FormattedAmount = TotalAmount.ToString("C");
}
}
通过[ConditionalGenerating]特性,可以控制某些代码只在特定条件下生成:
csharp复制[DtoGenerator]
[ConditionalGenerating("ENABLE_ADVANCED_FEATURES")]
public class AdvancedEntity
{
// 这些属性只在ENABLE_ADVANCED_FEATURES定义时才会生成DTO
}
批量生成策略:对于大型项目,建议按模块分批生成代码,避免一次性生成过多文件影响编译速度。
缓存利用:生成的代码会被Roslyn缓存,二次编译时只会重新生成有变动的部分。
IDE支持:VS2022对源码生成器有更好的支持,建议使用最新版本。
未启用源码生成器:
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>部分类声明缺失:
特性使用不当:
字段可见性问题:
命名冲突:
特性参数错误:
渐进式采用:
团队培训要点:
CI/CD调整:
项目结构建议:
code复制src/
├── MyApp.Domain/ # 实体定义
├── MyApp.Application/ # 服务层
├── MyApp.Web/ # DTO定义
└── generated/ # 生成的代码(可选)
命名规范:
版本控制:
经过半年多的实际使用,Mud代码生成器已经成为了我们团队不可或缺的开发工具。它不仅节省了约30%的编码时间,更重要的是减少了因手误导致的bug,使我们可以更专注于业务逻辑的实现。对于任何使用.NET进行开发的团队,我都强烈推荐尝试这套工具。