Validate Automapper configurations with AssertConfigurationIsValid

Automapper permit to map a class on another in order to transform source object into a destination object. We can do this transformation declaring mappings into a file for example MyProfile1.

We could have complex transformation for each property of the object or we can use an automapper behaviour that permit to copy the contents of property between the objects if thay have the same name property.

Just with this possibility that allows us to save lines of codes, we could find a problem. If we rename one of the property the copy will be lost, and we'll find this problem at runtime.

To overcome this problem, we can use the verification feature of AutoMapper, AssertConfigurationIsValid. We put this line of code in program.cs, at the start of the application to check mappings.

var mapper = app.Services.GetService();
mapper.ConfigurationProvider.AssertConfigurationIsValid();

For example if we have this two classes

public class Source
{
    public string Name { get; set; }
    public string Surname { get; set; }
    public string DescriptionRole { get; set; }
}

public class Destination
{
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Role { get; set; }
}

We renamed into the class Destination the property DescriptionRole in Role. If your mapping is

public class MyProfile1
{
    public MyProfile1()
    {
        CreateMap()
            .ForMember(dest => dest.Surname, opt
                => opt.MapFrom(src => src.Surname))
            .ForMember(dest => dest.Name, opt
                => opt.MapFrom(src => src.Name));
    }
}

The error when you start the application will be

Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters ================================================================================================================================================================== Source -> Destination (Destination member list) MyNameSpace.Source -> MyNameSpace.Destination(Destination member list) Unmapped properties: DescriptionRole

If you don't want to map this property, you can use Ignore.

CreateMap()
    .ForMember(dest => dest.Surname, opt
        => opt.MapFrom(src => src.Surname))
    .ForMember(dest => dest.Name, opt
        => opt.MapFrom(src => src.Name)
    .ForMember(dest => dest.Role, opt =>
        opt.Ignore());

Another problem occured when you define CreateMap multiple times in the same Profile class or another, the automapper use the last one loaded, but the could be different from each other.

With AssertConfigurationIsValid, if tou define the same trasformation in MyProfile1 and MyProfile2, the error will be

The following type maps were found in multiple profiles: MyNamespace.Source to MyNamespace.Destination defined in profiles: MyNamespace.MyProfile1 MyNamespace.MyProfile2

Comments

Popular posts from this blog

Using moq to test class that extends abstract class

The power of SpecFlow