AutoMapper is an AMAZING open source project that I can’t do without it in my WebAPI and MVC projects. However, creating the class maps can be a bit cumbersome. Creating maps is resource intensive due to heavy use of reflection, so best practices dictate creating all maps at app startup. This is typically done with a single file, like below:
public static class AutoMapperConfig
{
public static void RegisterMaps()
{
Mapper.CreateMap<SomeClass, SomeClassViewModel>();
Mapper.CreateMap<SomeClassViewModel, SomeClass>();
Mapper.CreateMap<SomeOjbectDto, SomeObject>();
Mapper.CreateMap<SomeOjbect,
SomeObjectDto>();
...
}
}
This works; however, this file can become gigantic quickly. Additionally, it’s
difficult to determine what maps already exist. This leads to duplicate maps or
even the dreaded “Missing type map configuration” errors. Because of this, I
created AutoMapperFramework
. This is how it works.
First, you need to install the package via NuGet:
PM> Install-Package AutoMapperFramework
Next, you need to decorate the classes you want to create maps for with one or
more of three header interfaces: IMapTo<T>
, IMapFrom<T>
, and
IHaveCustomMappings
. The first two are fairly self-explanatory: they will
create a default map with no additional options. Your code file will look
something like below:
public class SomeClass: IMapFrom<SomeClassDto>, IMapTo<SomeClassDto>
{
public string SomeProperty { get; set; }
public string ServerOnlyProperty { get; set; }
}
public class SomeClassDto
{
public string SomeProperty { get; set; }
}
Use IHaveCustomMappings
if you need special options for your map.
public class SomeClass: IHaveCustomMappings
{
public string SomeProperty { get; set; }
public string ServerOnlyProperty { get; set; }
public void CreateMappings(IProfileExpression configuration)
{
configuration.CreateMap<SomeClassDto, SomeClass>()
.ForMember(m => m.SomeProperty, opts =>
opts.MapFrom(s => s.SomePropertyWithADifferntName));
}
}
public class SomeClassDto
{
public string SomePropertyWithADifferntName { get; set; }
}
Finally, you just need to tell AutoMapperFramework
to load your maps. Create
a class like the one below and run it on app start (Global.asax
or anyway you
like). If you have maps that do not exist in the currently executing assembly,
just pass those types into LoadMappings
separately. LoadMappings
just
accepts an IEnumerable<Type>
.
public static class AutoMapperConfig
{
public static void RegisterMaps()
{
var mapLoader = new MapLoader(Mapper.Configuration);
mapLoader.LoadMappings(Assembly .GetExecutingAssembly()
.GetExportedTypes());
}
}
If you have questions, feel free to hit me up on the AutoMapperFramework
GitHub page. I’m also happy to accept any pull requests (as long as they
build).
Thanks you for reading!