Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoMapper.Mapper.CreateMap<TSource,TDestination>()' is obsolete

I have to classes Like

class A
{
 public int id {get; set;}
}

class B
{
 public C c {get; set;}
}

class C
{
 public int id {get; set;}
 public string Name {get; set;}
}

My requirement is to map id of class A to id of class C. Now what I was doing till now was: Mapper.CreateMap().ForMember(des => des.C.Id, src => src.MapFrom(x => x.id));

and it was working fine.

Now seems like Auto mapper has changed their implementation. and I am getting warning as below:

AutoMapper.Mapper.CreateMap()' is obsolete: 'Dynamically creating maps will be removed in version 5.0. Use a MapperConfiguration instance and store statically as needed, or Mapper.Initialize. Use CreateMapper to create a mapper instance.

I need to map some properties of classes which has different name and structure. Any help on this.

like image 569
Sharad Avatar asked Apr 04 '16 08:04

Sharad


People also ask

When should you not use AutoMapper?

If you have to do complex mapping behavior, it might be better to avoid using AutoMapper for that scenario. Reverse mapping can get very complicated very quickly, and unless it's very simple, you can have business logic showing up in mapping configuration.

What is Mapper CreateMap?

Mapper. CreateMap()' is obsolete: 'Dynamically creating maps will be removed in version 5.0. Use a MapperConfiguration instance and store statically as needed, or Mapper. Initialize. Use CreateMapper to create a mapper instance.

Where do I configure AutoMapper?

The MapperConfiguration instance can be stored statically, in a static field or in a dependency injection container. Once created it cannot be changed/modified. var configuration = new MapperConfiguration(cfg => { cfg. CreateMap<Foo, Bar>(); cfg.

What is AutoMapper profile?

automapper Profiles Basic Profile Profiles permit the programmer to organize maps into classes, enhancing code readability and maintainability. Any number of profiles can be created, and added to one or more configurations as needed. Profiles can be used with both the static and instance-based APIs.


2 Answers

Previously

  Mapper.CreateMap<Src, Dest>()
 .ForMember(d => d.UserName, opt => opt.MapFrom(/* ????? */));

The problem here is mapping definitions are static, defined once and reused throughout the lifetime of the application. Before 3.3, you would need to re-define the mapping on every request, with the hard-coded value. And since the mapping configuration is created in a separate location than our mapping execution, we need some way to introduce a runtime parameter in our configuration, then supply it during execution.

This is accomplished in two parts: the mapping definition where we create a runtime parameter, then at execution time when we supply it. To create the mapping definition with a runtime parameter, we “fake” a closure that includes a named local variable:

Mapper.Initialize(cfg => {

string userName = null;
cfg.CreateMap<Source, Dest>()
    .ForMember(d => d.UserName, 
        opt => opt.MapFrom(src => userName)
    );
});

For more information see this

For one or more classes

 cfg.CreateMissingTypeMaps = true;
 cfg.CreateMap<Source, Dest>()
    .ForMember(d => d.UserName, 
        opt => opt.MapFrom(src => userName)
    );

 cfg.CreateMap<AbcEditViewModel, Abc>();
 cfg.CreateMap<Abc, AbcEditViewModel>();
});

In mapping class

  IMapper mapper = config.CreateMapper();
  var source = new AbcEditViewModel();
  var dest = mapper.Map<AbcEditViewModel, Abct>(source);
like image 184
Anik Saha Avatar answered Sep 20 '22 16:09

Anik Saha


Another way that seems a bit cleaner is to make a MappingProfile class which inherits from the Profile class of AutoMapper

public class MappingProfile:Profile
{
    public MappingProfile()
    {
        CreateMap<Source1, Destination1>();
        CreateMap<Source2, Destination2>();
        ...
    }
}

Then you initialize the mapping with Mapper.Initialize(c => c.AddProfile<MappingProfile>()); in your startup code

That will allow you to use the mapping anywhere by calling

destination1Collection = source1Collection.Select(Mapper.Map<Source1, Destination1>);
like image 29
Leonard Lay Avatar answered Sep 19 '22 16:09

Leonard Lay