Object mapping made simple.
Twinify copies values from one object to another so you don't have to write that code by hand.
Describe the shape of the mapping once, then call Map<T>() wherever you need it.
var dto = mapper.Map<UserDto>(user);dotnet add package Twinify
dotnet add package Twinify.DependencyInjection
1. Describe your mapping in a profile:
public class UserProfile : MappingProfile
{
public UserProfile()
{
CreateMap<User, UserDto>()
.ForMember(d => d.FullName, opt => opt.MapFrom(s => $"{s.FirstName} {s.LastName}"))
.ForMember(d => d.Password, opt => opt.Ignore());
}
}2. Register it:
builder.Services.AddTwinify(cfg =>
{
cfg.AddProfile<UserProfile>();
});3. Use it:
public class UserService(IMapper mapper)
{
public UserDto GetUser(User user) => mapper.Map<UserDto>(user);
}That's it - properties with matching names are copied automatically. Anything you want to customize (rename, compute, ignore, convert) gets a line in the profile.
- Auto-matching - properties with the same name copy across without any configuration.
- Flattening - a destination property like
AddressCityautomatically picks upsource.Address.City. - Nested objects and collections - lists, arrays, dictionaries, and nested objects map recursively.
- Custom logic -
ForMember,Ignore,Condition,MapFrom,BeforeMap/AfterMap,ConvertUsing, and more, for the cases that need more than a straight copy. - Constructors and records - Twinify works out how to construct your destination type, including types with only a parameterized constructor.
Explain<TSource, TDestination>()- prints exactly where every destination member's value comes from, for when a mapping doesn't do what you expected.
| Package | What it's for |
|---|---|
Twinify.Abstractions |
The types you write against: IMapper, MappingProfile, CreateMap, etc. |
Twinify |
The mapping engine that actually executes your maps. |
Twinify.DependencyInjection |
AddTwinify(...) and friends, for ASP.NET Core / generic host apps. |
