AutoMapper and MediatR Going Commercial - What does this mean?

AutoMapper and MediatR Going Commercial - What does this mean?

4 min read - 08 Apr, 2025

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

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?

What is auto mapper for ?

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>();
        }
    }
}

What are the alternatives?

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, 

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
    });
 

Conclusion

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?

 

programming
On April 2nd 2025, Jimmy Bogard the developer behind AutoMapper and MediatR published an article on his blog titled "AutoMapper and MediatR Going Commercial". This is a small post about what is AutoMapper and what does it do, and what are the alternatives.
Published Tuesday, 8 April 2025


Related Articles