Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a breaking change between AutoMapper 2.0.0 and 2.2.0?

I updated from AutoMapper 2.0.0 to 2.2.0 today and realized the update broke some code. Wanted to ask about it here before posting as an issue on the automapper github site.

One of my destination types initializes a collection property like so:

public class PageOf<TModel> {     public PageOf()     {         Items = Enumerable.Empty<TModel>();     }      public IEnumerable<TModel> Items { get; set; } } 

With automapper 2.0.0, this was fine. When I updated to 2.2.0, mapping to this destination type caused a NotSupportedException with the message "Collection was of a fixed size." (That exception was wrapped inside an AutoMapperMappingException.)

I was able to fix the issue by changing the constructor code above to this:

public PageOf() {     Items = new List<TModel>(); } 

It seems as if AutoMapper 2.0.0 was discarding whatever value was in the Items property and using the set Property accessor, whereas AutoMapper 2.2.0 is just using the get property accessor and trying to modify the existing IEnumerable. It looks like Enumerable.Empty<TModel>() is just substituting a zero-length array, which would explain the exception.

Is this a bug? What in AutoMapper changed between 2.0.0 and 2.2.0 that would cause it to ignore the destination property setter and instead try to modify the existing collection?

Update:

As requested, here is the CreateMap call:

public class PagedQueryResultToPageOfItemsProfiler : Profile {     protected override void Configure()     {         CreateMap<PagedQueryResult<EstablishmentView>, PageOfEstablishmentApiModel>();     } } 

The PageOfEstablishmentApiModel class inherits from PageOf<EstablishmentApiModel>.

Here is the Mapper.Map code:

var query = Mapper.Map<EstablishmentViewsByKeyword>(input); var results = _queryProcessor.Execute(query); var model = Mapper.Map<PageOfEstablishmentApiModel>(results); // exception here 

If a special mapping configuration is necessary (for example .ConvertUsing(x => x)) in AutoMapper going from 2.0.0 to 2.2.0, we may have to hang onto the old version. I always liked how AM automatically converted collection properties, and without that, AM seems more like ValueInjecter.

like image 808
danludwig Avatar asked Nov 21 '12 20:11

danludwig


People also ask

What can I use instead of AutoMapper?

AutoMapper is one of the popular object-object mapping libraries with over 296 million NuGet package downloads. It was first published in 2011 and its usage is growing ever since. Mapster is an emerging alternative to AutoMapper which was first published in 2015 and has over 7.4 million NuGet package downloads.

What is .NET AutoMapper?

AutoMapper in C# is a library used to map data from one object to another. It acts as a mapper between two objects and transforms one object type into another. It converts the input object of one type to the output object of another type until the latter type follows or maintains the conventions of AutoMapper.

Is AutoMapper case sensitive?

The name should be the same but NOT CASE-SENSITIVE i.e. the name in source object can be “id” and that in the target object can be “ID”.

Where is AutoMapper configuration?

Where do I configure AutoMapper? ¶ Configuration should only happen once per AppDomain. That means the best place to put the configuration code is in application startup, such as the Global.


1 Answers

Have you tried to use the Map method that way: Mapper.Map<DestinationClass, SourceClass>(object to convert)

?

With the 2.2 version of AutoMapper, this is how we use it and it works fine for us.

like image 68
Nicolas Landier Avatar answered Sep 18 '22 03:09

Nicolas Landier