A high-performance, compile-time Source Generator for .NET that automatically creates DTO classes and mapping methods based on your entity definitions.
🚀 Zero Reflection | ⚡ Compile-Time Safety | 🛠 Highly Customizable
- Auto DTO Generation: Automatically generates
public partial class {Name}Dtofrom your entities. - Built-in Mapper: Generates
FromEntity()andToEntity()methods automatically. - Bidirectional Mapping: Supports Entity ↔ DTO conversion.
- Zero Overhead: No runtime reflection (System.Reflection); code is generated at compile time.
- Flexible Configuration:
[DtoName]: Rename properties in the DTO.[DtoIgnore]: Exclude sensitive properties (e.g., PasswordHash).[DtoVirtualProperty]: Add calculated/aggregated properties (e.g., FirstName + LastName -> FullName).
- Custom Logic Hooks: Support for partial methods or enforced interfaces (
IDtoMapperHooks) for custom mapping logic. - Modern C# Support: Supports
requiredmodifiers,initproperties, and nullable reference types.
(If you plan to publish to NuGet, add command here. For now, referencing locally:)
- Add the
DtoGeneratorproject reference to your project. - Add the
DtoGenerator.Sourceproject as an Analyzer.
Simply add [GenerateDto] to your class.
using DtoGenerator;
namespace MyApp.Models;
[GenerateDto]
public class User
{
public int Id { get; set; }
public required string Username { get; set; }
[DtoIgnore] // Won't appear in DTO
public string PasswordHash { get; set; }
}The generator creates UserDto in the background immediately.
var user = new User { Id = 1, Username = "admin", PasswordHash = "###" };
// Entity -> DTO
var dto = UserDto.FromEntity(user);
Console.WriteLine(dto.Username); // "admin"
// DTO -> Entity
var newUser = dto.ToEntity();By default, only properties declared in the current class are included.
To include all public properties from the entire inheritance chain, use:
[GenerateDto(IncludeBaseProperties = true)]
public class AdminUser : User
{
public string Role { get; set; }
}This will generate a AdminUserDto containing:
Id,Username(from baseUser)Role(fromAdminUser)
🔹 Note: Only
public instance propertiesfrom base classes are included. Private, protected, or static members are ignored.
Map UserEntity.UserEmail to UserDto.Email.
[DtoName("Email")]
public string UserEmail { get; set; }Combine fields into a new property in the DTO. Use entity to refer to the source object.
[DtoVirtualProperty("FullName", typeof(string), "entity.FirstName + \" \" + entity.LastName")]
public class User { ... }
// Or it can be written like this:
[DtoVirtualProperty("FullName", typeof(string), ExpressionMemberName=nameof(FullNameExpression))]
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public static Expression<Func<User, string>> FullNameExpression => a => $"{a.FirstName} {a.LastName}";
}You can hook into the mapping process to handle complex scenarios (e.g., splitting a string back into two fields during ToEntity).
Simply create a partial class file for your DTO.
// UserDto.Custom.cs
public partial class UserDto
{
partial void OnEntityCreated(User targetEntity)
{
// Custom reverse mapping logic
Console.WriteLine("Mapping finished!");
}
}Force the implementation of hooks using EnforceHooks = true.
[GenerateDto(EnforceHooks = true)]
public class User { ... }