Click here to Skip to main content
13,252,065 members (56,299 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

14.9K views
5 bookmarked
Posted 16 Sep 2016

ASP MVC with Automapper Profiles

, 17 Sep 2016
Rate this:
Please Sign up or sign in to vote.
IMapper interface is injected into constructors of my classes by Unity framework, but you can use any other DI framework or inject IMapper interface manually.

Introduction

I am using AutoMapper version 5.1.1.0 with IMapper interface (as opposed to static class Mapper).

IMapper interface is injected into constructors of my classes by Unity framework, but you can use any other DI framework or inject IMapper interface manually.

Motivation

I really like automapper functionality and I find it really useful especially when binding objects between layers. And I had a real struggle to make this work. So this should hopefully be a simple tutorial for those who would like to move from static Mapper class to IMapper interface. Or for those who never used AutoMapper before and would like to learn how to wire it all up. Because most of the tutorials I found were incomplete or out of date (using static Mapper class).

One Layer

If you have only one layer where you need to map between your models, I would recommend not to use AutoMapper Profiles and just go with a simple solution.

public static class MappingProfile
{
    public static MapperConfiguration InitializeAutoMapper()
    {
        MapperConfiguration config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<Question, QuestionModel>();
            cfg.CreateMap<QuestionModel, Question>();
            /*etc...*/
        });
 
        return config;
    }
}

This way, you create your MapperConfiguration object with all your mappings.

You can then create IMapper object from this configuration and inject it into your DI framework (Unity in my case).

public static class UnityWebActivator
{
    /// <summary>Integrates Unity when the application starts.</summary>
    public static void Start()
    {
        var container = UnityConfig.GetConfiguredContainer();
        var mapper = MappingProfile.InitializeAutoMapper().CreateMapper();
        container.RegisterInstance<IMapper>(mapper);
 
        FilterProviders.Providers.Remove
        (FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
        FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));
 
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
 
        // TODO: Uncomment if you want to use PerRequestLifetimeManager
        // Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule
        // (typeof(UnityPerRequestHttpModule));
    }
 
    /// <summary>Disposes the Unity container when the application is shut down.</summary>
    public static void Shutdown()
    {
        var container = UnityConfig.GetConfiguredContainer();
        container.Dispose();
    }
}

On line 7, MapperConfiguration is created and from that configuration by calling .CreateMapper() we get IMapper object.

On line 8, IMapper interface is binded to this mapper object (from line 7).

So from now, every time when DI sees IMapper object in constructor, it will provide this mapper object (line 7 again).

Now, example of object that requires IMapper:

public class BaseService
{
    protected IMapper _mapper;
 
    public BaseService(IMapper mapper)
    {
        _mapper = mapper;
    }
 
    public void AutoMapperDemo(){
        var questions = GetQuestions(token);
        return _mapper.Map<IEnumerable<Question>, 
        IEnumerable<QuestionModel>>(questions);
    }
 
    public IEnumerable<Question> GetQuestions(token){
        /*logic to get Questions*/
    }
}

This could be usage of automapper. You can use IMapper interface public method Map<> to map your classes. IMapper object is injected either by DI framework or manually when you create the BaseService object.

More Than One Layer

In the real world MVC application, you usually have more than one layer. You probably have something like WEB/BUSINESS/DB layer and WEB should not know about DB, because it talks only to BUSINESS layer.

That means with one configuration class you would have to reference DB project in your Web layer, otherwise you couldn’t map your objects.

And here comes for help automapper Profiles.

MappingProfile class again, now with profiles:

public static class MappingProfile
{
    public static MapperConfiguration InitializeAutoMapper()
    {
        MapperConfiguration config = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile(new WebMappingProfile());  //mapping between Web and Business layer objects
            cfg.AddProfile(new BLProfile());  // mapping between Business and DB layer objects
        });
 
        return config;
    }
}
//Profile number one saved in Web layer
public class WebMappingProfile : Profile
{
    public WebMappingProfile()
    {
        CreateMap<Question, QuestionModel>();
        CreateMap<QuestionModel, Question>();
        /*etc...*/
    }
}
 
//Profile number two save in Business layer
public class BLProfile: Profile
{
    public BLProfile()
    {
        CreateMap<BLModels.SubModels.Address, DataAccess.Models.EF.Address>();
        /*etc....*/
    }
}

This way Web layer doesn’t need to reference DB layer.

All other steps are the same as for one layer.

Summary

I think that automapper can be a very useful tool if used properly, but it is sometimes really hard to find tutorials that are up to date. I highly recommend you to read autommaper wiki if you struggle.

I encourage you to write in comments how to wire this with for example Ninject or Castle Windsor.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

xszaboj
United Kingdom United Kingdom
No Biography provided

You may also be interested in...

Comments and Discussions

 
QuestionI need help Pin
Member 133973356-Sep-17 20:55
memberMember 133973356-Sep-17 20:55 
QuestionMapping profiles are not extensible Pin
Lechuss5-Apr-17 2:54
memberLechuss5-Apr-17 2:54 
QuestionMappingProfile Location Pin
adasasdas30-Jan-17 9:05
memberadasasdas30-Jan-17 9:05 
AnswerRe: MappingProfile Location Pin
xszaboj31-Jan-17 1:47
memberxszaboj31-Jan-17 1:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.171114.1 | Last Updated 17 Sep 2016
Article Copyright 2016 by xszaboj
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid