1

I am following the pattern used here, but it seems that it doesn't work for mappings unless I call AutoMapperWebConfiguration.Configure() directly before the mapping takes place.

I was under the impression that configuration for AutoMapper was very expensive -- what's the point of following this pattern if I need to call Configure() before every call?

AutoMapperWebConfiguration:

    public static class AutoMapperWebConfiguration
    {
        private static List<Profile> _profiles;

        public static void Configure(List<Profile> profiles)
        {
            _profiles = profiles;

            Configure();
        }

        public static void Configure()
        {
            Mapper.Initialize(cfg =>
            {
                foreach (var profile in GetProfiles())
                {
                    cfg.AddProfile(profile);
                }
            });
        }

        public static List<Profile> GetProfiles()
        {
            var profiles = new List<Profile>
            {
                new UserViewModelProfile(), new OrderViewModelProfile()
            };

            profiles.AddRange(_profiles);

            return profiles;
        }
    }

    public class UserViewModelProfile : Profile
    {
        protected override void Configure()
        {
            CreateMap<User, UserDetailViewModel>();
        }
    }
}

The mapping:

var userDetailViewModels = Mapper.Map<List<User>, List<UserDetailViewModel>>(users);

The call to AutoMapperWebConfiguration.Configure() occurs in Application_Start():

AutoMapperWebConfiguration.Configure(AutoMapperCoreConfiguration.GetProfiles());

When this action method is loaded (where the mapping appears), I get the exception:

Missing type map configuration or unsupported mapping.

This disappears when I call AutoMapperWebConfiguration.Configure() directly before the mapping takes place. Am I doing something wrong?

Community
  • 1
  • 1
Cody
  • 8,686
  • 18
  • 71
  • 126

2 Answers2

0

I guess in your case it doesn't work because you have mapping configured for entity and its view model, but not for the list of entities and the list of view models.

I'm using AutoMapper the following way:

  1. There is AutoMapperInitializer (configurator in your case)

    public static class AutoMapperInitializer {
        public static void Init() {
            // Your models maps goes here
            Mapper.CreateMap<RegisterViewModel, User>();
            Mapper.CreateMap<User, UserViewModel>().Bidirectional();
        }
    
        public static void Bidirectional<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression) {
            Mapper.CreateMap<TDestination, TSource>();
        }
    }
    
  2. In Application_Start the init method is called

    protected void Application_Start() {
        //...
    
        AutoMapperInitializer.Init();
    }
    
  3. Now I can use mapping in my controllers code

    UserViewModel vm = Mapper.Map<UserViewModel>(user);
    

or for the list

    [HttpPost]
    public JsonResult AjaxList() {
        IList<User> users = UserRepository.Find().ToList();
        IEnumerable<UserViewModel> vm = users.Select(u => Mapper.Map<UserViewModel>(u));
        return Json(vm);
    }

Hope it will help.

tabalin
  • 2,303
  • 1
  • 15
  • 27
0

After seemingly random bugs where none of my maps were initialize, I stumbled onto the issue.

I was calling Mapper.Initialize in my Application_Start, but was also calling it in other places as a means to create maps -- I had read that Initialize had better performance than CreateMap.

What I didn't realize was that every call to Mapper.Initialize would wipe the slate clean and remove all maps previously created. Once I removed the multiple calls to Initialize, my issues were gone.

Hopefully this helps others, who like me can't see the forest for the trees.

Cody
  • 8,686
  • 18
  • 71
  • 126