3.2.0

@jbogard jbogard released this Apr 15, 2014

AutoMapper 3.2.0 now supports the following target platforms:

  • .NET 4+
  • Silverlight 5
  • Windows Phone 8+
  • Windows 8+
  • Windows Universal Apps (WPA81)
  • Xamarin MonoDroid
  • Xamarin MonoTouch

As part of this release we had 66 commits which resulted in 48 issues being closed.

Features

#487 Queryable mapping bug

Test cases and partial fix for mapping child collections. See http://stackoverflow.com/q/20046521/311289 for a bigger description.

#446 Evaluate IMemberConfigurationExpression conditions before resolve value

Hi,

it would be nice if conditions are evaluated before ResolveValue is called in order to avoid executing code (i.e. calling the getter of the underlying property) which won't be needed anyway because a condition will return false.

Specifing IMemberConfigurationExpression.Ignore() would work since this is evaluated before resolving the value but my use case depends on dynamic variables.

Source:

TypeMapObjectMapperRegistry::PropertyMapMappingStrategy:MapPropertyValue()

Content trimmed. See full issue

#429 Nuget ios version 3.1.0 does not compile for device

Setup:

  • xamarin ios 7.0.x, xamarin ios vs2012 1.8
  • create a new ios helloworld project, reference Automapper nuget
  • In MyViewController add
public class Test1 { public string Value1 { get; set; } }
public class Test2 { public string Value1 { get; set; } }
  • In ViewDidLoad add
    Content trimmed. See full issue

#422 support for optional args

added support for optional args with default values

#409 Handle NHibernate proxies of Abstract Type

Hi, I would like to be able to call

Mapper.Map<Animal, AnimalDto>(animal);

Where Both Animal and AnimalDto are abstract classes AND animal is in fact a proxy to a NHibernate object. I would imagine this working by using Mappings similar to this:

Mapper.CreateMap<Animal, AnimalDto>()
.PreMap(animalProxy => Helper.CastToEntity(animalProxy))
.Include<Cat, CatDto>
.Include<Dog, DogDto>

Content trimmed. See full issue

#354 IgnoreMap attribute

We use Automapper to map between models and view models. In some of our view models we want to map in a value from a model but never want it to be mapped back into the model itself. These values/properties are used on the view model in a read only fashion and considered reference only. We were hoping that by adding the ignore attribute to our view model would allow us to map a value in from the model but not back into the model but it appears to work both ways. We use the map config to write ignore() for each of these values but would rather use attributes. How about an overload to the ignore map attribute that allows us to configure the allowed or blocked direction of the map operation?

#256 AutoMapper caching objects when mapping twice

When you have a tree heirarcy of objects, and the same value exists in two places of the tree (but with different child values), and when mapping the second instance of the item - it uses the child values of the first instance, instead of re-evaluating what the child values should be.

Here is my example:

class Tag {
int Id {get; set;}
string Name {get; set;}
IEnumerable<Tag> ChildTags {get; set;}
}

public void Test()

Content trimmed. See full issue

#255 Are there any plans to release WinRT version ?

I'm building Metro app based on C#/XMAL approach and I would really like to use automapper. So, is there a chance to get it ? Currently I'm not able to add it the project due to that automapper is not complied against winRT.

Preferable : it would be nice to get it thru nuget package.

#254 Support for yielding records from DataReaderMapper rather than using a list

For the most part, the DataReaderMapper has always worked well for me. The use of a List rather than yielding records was never that big of a deal for the majority of my typical scenarios. However, I finally have a legitimate need for yielding the records due to some rather large result sets.

You might decide against merging this, but I wanted to offer it since others have asked for this ability. All of the existing unit tests pass and I also tested the changes in my own projects. Depending on how AutoMapper is being applied to data readers, there are some scenarios that could be problematic due to deferred execution.

For example, code written such as this would now fail because the reader will already be closed when iteration of the enumerable begins. The reader will not actually be processed until deferred execution is triggered.

public IEnumerable<Person> GetAllPersonRecords()
{
   using (var connection = CreateConnection())
   using (var command = CreateCommand())

Content trimmed. See full issue

#247 Support Entity Framework in CreateMapExpression

Hello,

I have made changes to enhance the support for building queries that translate to SQL using the Entity Framework.

  • Allow nested queries that can be mapped to SQL.
  • Added support for mapping to Arrays using CreateMapExpression.
  • Created Unit Test cases for Linq Expressions.
 Mapper.CreateMap<Entity, EntityViewModel>()
.ForMember(m => m.SubEntityNames, o => o.MapFrom(f => f.SubEntities.Select(e => e.Name)));

Content trimmed. See full issue

#209 Shortcut for mapping subtypes

instead of writing:
.ForMember(dto => dto.Contact, opt => opt.MapFrom(src => Mapper.Map<SOHeader, SalesOrderContact>(src)))

it would be nice to write something like

           .ForMember(dto => dto.Contact, opt => opt.UsingMap<SOHeader, SalesOrderContact>() )

Improvements

#489 Support for WP8.1

Hi Jimmy!
Is it possible for you to add support for WP8.1/Universal Apps?

#482 Mapper.AssertConfigurationIsValid()

I like to have one unit test for each profile I've defined, so I use the overload of Mapper.AssertConfigurationIsValid() that takes a profile name. However, I'd rather have a type-safe reference to the profile than a string, since if I happen to have misspelled the profile name in the test, my test will always pass.

I would therefore suggest the addition of the following method to the Mapper class:

public static void AssertConfigurationIsValid<TProfile>()
    where TProfile : Profile, new()
{
    AssertConfigurationIsValid(new TProfile().ProfileName);
}

As far as I can tell that's all it would take.
Content trimmed. See full issue

#480 Issue #473. Static DynamicMap and CreateMap APIs should be thread-safe

It's variant of changes. Mostly idea, because of strong types are used and not all platforms were tested.

#473 Static DynamicMap and CreateMap APIs should be thread-safe

I know, there have been closed bug reports in the past (#208, #50), but we just stumbled into the same trap. Since AutoMapper's primary API is static and AutoMapper is meant to be used in complex applications, we automatically assumed that it must be thread-safe.

Instead, it is not - calling DynamicMap and CreateMap on different threads can lead to (and, in our case, has lead to) multithreading issues. As static APIs are bound to be called from different threads, I want to again raise this request for thread-safe static APIs.

(Indeed, the static DynamicMap API is useless as long as not thread-safe, isn't it? In what context could you ever use it in an application?)

#468 Update QueryableExtensions.cs

Handles null source property so it will not create an object with possible non-nullable properties which would result in an exception.

#466 Set ResolutionContext.DestinationValue when it is resolved

When a value is resolved, set it on ResolutionContext.DestinationValue so that subsequent mappers in the resolution chain can make use of the resolved value.

This is in regards to my efforts to use AutoMapper to map from a DTO to a domain model that uses DDD, see https://groups.google.com/forum/#!topic/automapper-users/_xm0A-mA03U.

#465 Linq expression builder doesn't support max depth

There is a MaxDepth configuration option for CreateMap, but seems the linq expression doesn't respect that. So if I have circular references of an entity and its property, .Project() would result in stackoverflow.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using System.Data.Entity;

Content trimmed. See full issue

#464 3.1.1 not CLS-Compliant

Automapper 2.X was CLS-Compliant. Is there a reason that 3.1.1 is no longer CLS Compliant? Can the next version be CLS-Compliant again?

#458 AutoMapper.Net4.dll twofold in main project folder and References

When I use NuGet to get AutoMapper, AutoMapper.Net4.dll appears properly in References directory and in main project folder. It looks bad when same dll appears in two places - waste of resources. It is really needed in main folder? Any other NuGet project has that behavior :/
automapper

#451 ReverseMap and Inheritance

I'm trying to do reverse mapping rules to go back and forth between complex objects using inheritance on both sides. When mapping in the reverse way, it seems that the map create an instance of the parent class instead of the child class like it does in normal mode.

namespace ReverseInheritanceTest
{
    [TestFixture]
    public class ReverseInheritanceTest
    {
        [SetUp]
        public void SetUp()
        {

Content trimmed. See full issue

#448 AutoMapper logo broken in ReadMe.

#447 Issue #274 - Reopened for Enumerable.Empty<>

Pull request from thread for Isssue #274

#445 Provide context information when mapping

I've got a situation where I want to create a mapping, but the mapping depends on the individual call to Map. For example, say I have the following source and destination objects:

public class Restaurant
{
    ...
    public DbGeography Location { get; set; }
}

public class RestaurantDto
{

Content trimmed. See full issue

#444 Fixed a NullReferenceException thrown by QueryableExtensions with Inherited Explicit Mapping

Resolves issue #443.

Fixes NullReferenceException in PropertyMap.ResolveExpression method (used by QueryableExtensions ) when Explicit Mapping is inherited.

#443 QueryableExtensions throw NullReferenceException when Inherited Explicit Mapping is used

PropertyMap.ResolveExpression method throws a NullReferenceException when trying to .Project().To<>() using inherited MapFrom mappings.

#438 Updating NuGet package to version 3.1.1.0 adds Automapper.Net4.dll file to project

After upgrading from AutoMapper 3.1.0.0 to 3.1.1.0, a file entry has been added to the root of the project pointing to the Automapper.Net4.dll file sitting in the packages directory. Was that intentional? If so, what's the purpose / reason for this file getting added to the project?

#436 TypeMapFactory fields should not be static

The TypeMapFactory class has some static fields in it that are causing some problems in a multi threaded environment (see mailing list, "Automapper Invalid Operation and Index Out of Range exceptions", for more explanation).

The fields are:

private static readonly IDictionaryFactory DictionaryFactory = PlatformAdapter.Resolve();
private static readonly Internal.IDictionary<Type, TypeInfo> _typeInfos =
DictionaryFactory.CreateDictionary<Type, TypeInfo>();

Mark

#424 ReverseMap() fails

I found a strange behavior in ReverseMap().
I have to map these classes together, in both ways:

public class MyClass1
{
    public int MyProperty1 { get; set; }
}
public class MyClass2
{
    public int MyProperty1 { get; set; }
    public int MyProperty2 { get; set; }

Content trimmed. See full issue

#423 Added a new mapping expression - IgnoreAllPropertiesWithAnInaccessibleSetter()

IgnoreAllPropertiesWithAnInaccessibleSetter() supports scenarios where the destination type contains several properties with private or protected setters that should not be mapped from the source type.

I added a test class with four "facts" for this, and they all pass. I also added summary documentation.

This addresses #187 (and it appears to be related to #173 and #218).

(Note: I previously submitted a pull request with a different solution involving an overload to AssertConfigurationIsValid(), but I believe this is a better solution because it allows more fine-grained control and doesn't make any existing methods obsolete. I also managed not to screw up the line endings this time :))

#416 ValueResolver in child mapping incorrectly uses parent type instead of child type of property

A bit difficult to explain except trough code. I understand this is probably an edge case but it's something we ran into (our backend is quite inconsistent at times this is an attempt to fix that).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using AutoMapper;

namespace TestConsoleApplication

Content trimmed. See full issue

#410 Update QueryableExtensions.cs

Handles null source property so it will not create an object with possible non-nullable propeerties which would result in an exception.

#403 Project().To fails when Source & Destination types have inner ICollection of different types

Using AutoMapper version 3.1.0.1032 with EntityFramework 5. Attempting to use the projection features of AutoMapper.

Consider the following:

namespace Domain
{    
   public class Scenario
   {
       public int Id { get; set; }
       public string Name { get; set; }
       public ICollection<Domain.Characteristic> Characteristics { get; set; }

Content trimmed. See full issue

#399 StackOverflowException when calling Project on an IQueryable with nested classes

If I have a class with a property that it's of the same type of the class, whenever I used the Project extension on an IQueryable of the class, the AutoMapper returns a StackOverflowException.

Using for example the same source and destinations classes of the AutoMapper.UnitTests.MaxDepthTests, if we run the following code the exception is raised:

        Mapper.CreateMap<Source, Destination>()
            .ForSourceMember(src => src.Children, opt => opt.Ignore())
            .ForSourceMember(src => src.Parent, opt => opt.Ignore());

        var destination = _source.Children.AsQueryable().Project().To<Destination>();

Thanks,
Content trimmed. See full issue

#281 AutoMapper Condition check

Hi,
I am using AutoMapper 2.2.1-ci9000, and I have the following problem:

I would like to map property only if destination value is null, I am using the code:

Mapper.CreateMap<ADGroup, Group>()
        .ForMember(dep => dep.Image, opt =>
                                                        {
                                                            opt.Condition(r => r.DestinationValue == null);
                                                            opt.MapFrom(src => _groups.GetImage(src)); //  <-- lazy load photo

Content trimmed. See full issue

#279 byte array to byte array is very slow.

Mapping a byte[] property to a byte[] property is terribly slow. It is typically 50 times slower than a plain Array.Copy(). It seems automapper is handling byte[] as an IEnumerable and maps every byte individually.

One of the mapped classes (tested with Data = new byte[1000])
public class Document
{
public int Id { get; set; }
public byte[] Data { get; set; }
}

Adding the following map solves the issue:
Mapper.CreateMap<byte[], byte[]>().ConstructUsing(src =>
Content trimmed. See full issue

#263 Checking Destination Value before copying

I am trying to copy source value only if the destination value is null. I am using the following map

     Mapper.CreateMap<BM.AudioSetting, BM.AudioSetting>()
            .ForMember(dest => dest.MSOffsetInherited, opt =>
                                                           {
                                                               opt.Condition(src => src.DestinationValue == null);
                                                               opt.MapFrom(src => src.MSOffset);
                                                           });

In my condition I am checking to make sure the destination value is null before mapping. The problem is the copying is happening all the time regardless of the destination value.

Content trimmed. See full issue

Bugs

#476 Mapper.Initialize with null or NOOP throws odd exception

Using version 3.0.0.

Following code blows a gasket:

    public void Initialize(string assemblySearchString)
    {
        List<Profile> profiles = new List<Profile>();
        var profileType = typeof(Profile);
        var assemblies = AppDomain.CurrentDomain.GetAssemblies()
            .Where(a => a.FullName.Contains(assemblySearchString));
        foreach (var assembly in assemblies)

Content trimmed. See full issue

#462 Fix for invalid cast exception when trying to map to not IList class

Fix for invalid cast exception when trying to map with EnumerableMapper to destination of IEnumerable, but not IList type

#457 Issue with Automapper.targets

Including the latest added automapper.targets file breaks my build for some weird reason, It gives a lot of assembly reference not found errors:

.Web\Domain\Auth\SecretRepository.cs(8,30,8,34): error CS0234: The type or namespace name 'Auth' does not exist in the namespace 'HearthstoneTracker' (are you missing an assembly reference?)
.Web\Domain\Auth\SecretRepository.cs(9,30,9,34): error CS0234: The type or namespace name 'Auth' does not exist in the namespace 'HearthstoneTracker' (are you missing an assembly reference?)
.Web\Domain\Auth\SecretRepository.cs(15,37,15,54): error CS0246: The type or namespace name 'ISecretRepository' could not be found (are you missing a using directive or an assembly reference?)
.Web\Domain\Auth\SecretRepository.cs(15,56,15,71): error CS0246: The type or namespace name 'ILookupUsername' could not be found (are you missing a using directive or an assembly reference?)

And that goes on an on for the referenced Class librariy in this web project.

Nothing fancy in the project (asp.net mvc 5 project referencing one class library). If I remove the Automapper.targets file from the project, everything is ok.

Checking the build log for both cases, it looks like when adding .targets file. csc.exe is not adding my referenced class library as a /reference: argument.

Is there some conflict with the 'ResolveAssemblyReferences' target maybe?


Ok, I found the issue.

Replace

<CoreBuildDependsOn>
  CopyAutoMapperAssembly;
  $(CoreBuildDependsOn)
</CoreBuildDependsOn>

With:

<CoreBuildDependsOn>
  $(CoreBuildDependsOn);
  CopyAutoMapperAssembly
</CoreBuildDependsOn>

I would send a PR normally, but i'd have to clone the whole repo to change 2 lines. Looks like an easy fix :-)

#452 DataReader mapping returns wrong type - BuilderKey.Equals() is wrong

I've been having an intermittent problem with mapping from a IDataRecord (SqlDataReader) to a variety of POCO objects. All my data records are identical (same column names) but I can map them into different classes.

A typical error would be

"X.DistributorSummary" is not of type "X.ShareClassSummary" and cannot be used in this generic collection.
Parameter name: value
   at System.ThrowHelper.ThrowWrongValueTypeArgumentException(Object value, Type targetType)
   at System.Collections.Generic.List`1.System.Collections.IList.Add(Object item)
   at AutoMapper.Mappers.DataReaderMapper.LoadDataReaderViaList(IDataReader dataReader, IMappingEngineRunner mapper, Build buildFrom, ResolutionContext resolveUsingContext, Type elementType)

Content trimmed. See full issue

#450 Getting "Conflicting File Modification Detected" for NuGet package w/ AutoMapper dependency

I was experimenting with creating my own NuGet package for a custom library, and I made AutoMapper one of the dependencies. When I went to install my custom NuGet package, I ran into this error dialog:

conflicting file dialog

This appears to be related to the "AutoMapper.Net4.dll" link, which is the current solution for issue #318.

Potentially better solutions include (1) the technique is outlined in this blog post by Alex Yakunin or (2) adding a post-build event command line that uses xcopy to make sure the DLL ends up in the output directory, as in EntityFramework.SqlServerCompact.

#433 Cannot Ignore Setter Only Property

tried by property name and get

        Mapper
            .CreateMap<Source, Desitination>()
            .ForMember("Property", o => o.Ignore());

AutoMapper.AutoMapperMappingException
Missing type map configuration or unsupported mapping.

Mapping types:
Source -> Desitination

Content trimmed. See full issue

#432 ForAllMembers condition breaks after upgrading to 3.1.0

We just upgraded from 3.0.0 to 3.1.0 and started getting an issue with mappings with the following definition:

.ForAllMembers(o => o.Condition(c => !c.IsSourceValueNull));

This was previously functioning correctly and would not attempt to map properties which did not have a source value. After the upgrade, it seems that Automapper, when faced with a destination member that has no matching source member, will attempt to map from the source type to the destination member. This then throws a mapping exception because there is no mapping definition for the source type to any of the destination property types. Previously, Automapper seemed to rightfully ignore members which did not have a matching source member.

We changed the condition line to:

Content trimmed. See full issue

#430 Collection mapping is broken after upgrade to Automapper 3.*, when collection is lazily initialized

Consider these classes:

    class Master
    {
        public int Id { get; set; }
        public ObservableCollection<Detail> Details
        {
            get
            {
                return details ?? (details = new ObservableCollection<Detail>());
            }

Content trimmed. See full issue

#425 The EntityCollection has already been initialized in automapper since 2.2.0 version

Hello!

Starting with 2.2.0 version of automapper I'm getting "The EntityCollection has already been initialized" exception while trying to map from data model into an EntityObject from edmx model (generated by EF DB first method) containing EntityCollection field with "((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection" method in setter.

I tried filling the EntityCollection property using add() method and .AfterMap in Map configuration. It works ok in such way, except for it creates a problem with relationships recursion.

I tried looking for the commit which have broken this stuff and found it: 6c38546

So it turned out that changing

object destinationValue = propertyMap.GetDestinationValue (mappedObject);

Content trimmed. See full issue

#413 Automapper setting a property name Type incorrectly

I have an Entity with the property named TYPE and when I create the mapping there is no additional mapping for this field.

When I query the entity I get entity.TYPE = "XYZ"

However, right after I execute

Mapper.Map(source: dto, destination: entity);

my destination now has entity.TYPE = "MyProject.DTO" where my MyProject.DTO is the fullname of the GetType() function.

Is this a known issue? Or is there a restriction in regards of naming of the fields?
Content trimmed. See full issue

Where to get it

You can download this release from:

Downloads