On April 2nd 2025, Jimmy Bogard the developer behind AutoMapper and MediatR published an article on his blog titled "AutoMapper and MediatR Going Commercial". I am not going to write about MediatR as I don't use it, and also I don't like to get into the debate of patterns, as I believe it's a very subjective argument.
AutoMapper is a simple little library built to solve a deceptively complex problem - getting rid of code that mapped one object to another. This type of code is rather dreary and boring to write, so why not invent a tool to do it for us?
AutoMapper is for mapping one class to another, when working with databases this type of code is useful when you want to map a database object to a view object, take the following code example:
// Source model
public class BlogItemSource
{
public string Title { get; set; }
public string Content { get; set; }
public string Description { get; set; }
public DateTime Date { get; set; }
public string[] Tags { get; set; }
public string Author { get; set; }
}
// Target/destination model
public class BlogItemViewModel
{
public string Title { get; set; }
public string Content { get; set; }
public string Summary { get; set; } // Different name than source
public DateTime PublishedDate { get; set; } // Different name than source
public string[] Categories { get; set; } // Different name than source
public string AuthorName { get; set; } // Different name than source
public string Slug { get; set; } // Property that needs transformation
}
public class BlogMappingProfile : Profile
{
public BlogMappingProfile()
{
CreateMap<BlogItemSource, BlogItemViewModel>()
.ForMember(dest => dest.Summary, opt => opt.MapFrom(src => src.Description))
.ForMember(dest => dest.PublishedDate, opt => opt.MapFrom(src => src.Date))
.ForMember(dest => dest.Categories, opt => opt.MapFrom(src => src.Tags))
.ForMember(dest => dest.AuthorName, opt => opt.MapFrom(src => src.Author))
.ForMember(dest => dest.Slug, opt => opt.MapFrom(src => src.Title.ToLower().Replace(" ", "-")));
}
}
The method above is the equivalent of writing the following code as an extension method:
using System;
using System.Linq;
namespace YourNamespace.Extensions
{
/// <summary>
/// Extension methods for blog item mapping
/// </summary>
public static class BlogItemExtensions
{
/// <summary>
/// Converts a BlogItemSource to a BlogItemViewModel
/// </summary>
/// <param name="source">The source blog item</param>
/// <returns>A mapped BlogItemViewModel</returns>
public static BlogItemViewModel ToDto(this BlogItemSource source)
{
if (source == null)
return null;
return new BlogItemViewModel
{
// Map direct properties
Id = source.Id,
Title = source.Title,
Content = source.Content,
// Map renamed properties
Summary = source.Description,
PublishedDate = source.Date,
AuthorName = source.Author,
// Transform properties
Slug = source.Title?.ToLowerInvariant().Replace(" ", "-"),
// Map collections
Categories = source.Tags?.ToArray() ?? Array.Empty<string>(),
// Add any default values for properties not in source
IsPublished = true
};
}
/// <summary>
/// Converts a collection of BlogItemSource to BlogItemViewModel objects
/// </summary>
/// <param name="sources">The source collection</param>
/// <returns>A collection of mapped BlogItemViewModel objects</returns>
public static IEnumerable<BlogItemViewModel> ToDto(this IEnumerable<BlogItemSource> sources)
{
return sources?.Select(source => source.ToDto()) ?? Enumerable.Empty<BlogItemViewModel>();
}
}
}
For object mapping in .NET, AutoMapper alternatives include Mapster, Mapperly, and AgileMapper, offering different approaches and performance characteristics. Below are some benchmarks of AutoMapper vs Mapster,
"Writing mapping methods is a machine job. Do not waste your time, let Mapster do it." - Mapster is attribute based and allows develops to add attributes to their data classes and this will create Dto's.
[AdaptTo("[name]Dto"), GenerateMapper]
public class Student {
...
}
This is all gravy if you need to map to a dto of the same name and signature but if the names of the properties are different, you will most likely need to write configuration code:
config.AdaptTo("[name]Dto")
.ForType<Student>(cfg => {
cfg.Map(poco => poco.LastName, "Surname"); //change property name
cfg.Map(poco => poco.Grade, typeof(string)); //change property type
});
Talking about coding patterns can be a Zero-sum game when talking about development as it's often an objective decision, however the DTO or Data transfer object is common practice when implementing API's. However I don't feel that AutoMapper is solving a problem that hasn't already been solved, and isn't solvable by an alternative method, is the commercialisation of this product really in-line with it's real world value to development teams?