Rob White
Rob White

Reputation: 1002

Automapper, Mapping config isn't persisting

So the problem.

Ive added

AutoMapperConfig.Configure();

to the application_Start in global.asax

it runs the code

Mapper.Initialize(x =>
{
  x.AddProfile<DomainToViewModelMappingProfile>();
  x.AddProfile<ViewModelToDomainMappingProfile>();
});

Mapper.AssertConfigurationIsValid();

which runs

public class DomainToViewModelMappingProfile : Profile
{
    protected override void Configure()
    {

        Mapper.CreateMap<DBO.User, ViewModels.UserViewModel>();
    }
}

and

public class ViewModelToDomainMappingProfile : Profile
{
    protected override void Configure()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<ViewModels.UserViewModel, DBO.User>();
        });
    }
}

and everything compiles and runs fine.

but in the controller:

UserViewModel model = new UserViewModel();
User user = userService.GetUser(2);
model = Mapper.Map<User, UserViewModel>(user); //this line fails as mapping doesnt exist
return View();

but if i add the mapping config in the controller method

Mapper.CreateMap<ViewModels.UserViewModel,DBO.User>();
UserViewModel model = new UserViewModel();
User user = userService.GetUser(2);
model = Mapper.Map<User, UserViewModel>(user); //Works great
return View();

it works fine.

ignore the different syntax with automapper. Ive tried the deprecated and new way of mapping and both fail.

Thanks

Upvotes: 2

Views: 1584

Answers (3)

MaKCbIMKo
MaKCbIMKo

Reputation: 2820

The problem is that you're calling Initialize method inside your Profile which leads to overriding your already existed mappings:

public class ViewModelToDomainMappingProfile : Profile
{
    protected override void Configure()
    {
        // you should not to call Initialize method inside your profiles.
        Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<ViewModels.UserViewModel, DBO.User>();
        });
    }
}

And here, you have two ways:

Way #1 (using the static API - deprecated)

public class DomainToViewModelMappingProfile : Profile
{
    protected override void Configure()
    {
        Mapper.CreateMap<DBO.User, ViewModels.UserViewModel>();
    }
}

public class ViewModelToDomainMappingProfile : Profile
{
    protected override void Configure()
    {
        Mapper.CreateMap<ViewModels.UserViewModel, DBO.User>();
    }
}

// initialize your mapper by provided profiles
Mapper.Initialize(x =>
{
  x.AddProfile<DomainToViewModelMappingProfile>();
  x.AddProfile<ViewModelToDomainMappingProfile>();
});

Mapper.AssertConfigurationIsValid();

Way #2 (using the instance API)

// in this case just call CreateMap from Profile class - its the same as CreateMap on `cfg`
public class DomainToViewModelMappingProfile : Profile
{
    public DomainToViewModelMappingProfile()
    {
        CreateMap<DBO.User, ViewModels.UserViewModel>();
    }
}

public class ViewModelToDomainMappingProfile : Profile
{
    public ViewModelToDomainMappingProfile()
    {
        CreateMap<ViewModels.UserViewModel, DBO.User>();
    }
}

// initialize you mapper config
var config = new MapperConfiguration(cfg => {
    cfg.AddProfile<DomainToViewModelMappingProfile>();
    cfg.AddProfile<ViewModelToDomainMappingProfile>();
});

// and then use it
var mapper = config.CreateMapper();
// or
var mapper = new Mapper(config);
var dest = mapper.Map<Source, Dest>(new Source());

In the Way #2 you will need to store you mapper configuration somewhere (static field, DI), and then use it inside your controller. I would like to suggest to inject the Mapper instance into your controller (e.g. using some DI container).

Hope it will help.

Upvotes: 1

Rob White
Rob White

Reputation: 1002

OK, thanks to MaKCbIMKo for pointing me in the right direction

As described i dont have to initialize as its already being done in the automapperconfig.

the syntax once in the profile is simply.

CreateMap<ViewModels.UserViewModel, DBO.User>(); 

Upvotes: 0

Ahmado
Ahmado

Reputation: 58

try to override "ProfileName" :

public class DomainToViewModelMappingProfile : Profile
{
 public override string ProfileName
    {
        get
        {
            return "DomainToViewModelMappingProfile";
        }
    }

protected override void Configure()
{

    Mapper.CreateMap<DBO.User, ViewModels.UserViewModel>();
}
}

Upvotes: 0

Related Questions