Search code examples
c#automapperautomapper-4

AutoMapper with dynamic type: Missing type map configuration or unsupported mapping


Answer: CreateMissingTypeMaps must be set to true to make dynamic mapping working.

    public IEnumerable<T> GetDummies<T>(IEnumerable<dynamic> dummies)
    {
        var config =
            new MapperConfiguration(c => { c.CreateMissingTypeMaps = true; });

        IMapper mapper = config.CreateMapper();
        return dummies.Select(mapper.Map<T>).ToList();
    }

I have wrapper around Entity Framework to perform queries to database. I want to allow user to select only required properties, but keep result of entity type.

This is dummy code (without using EF, but having same issue)

class Program
{
    static void Main(string[] args)
    {
        var dummies = new[]
        {
            new DummyContainer
            {
                Name = "First",
                Description = "First dummy",
                DummyNumbers = new List<int> { 1, 2, 3 },
                Foo = new FooThingy { Title = "Foo thingy" }
            }
        };

        var smallDummies = dummies.Select(d => new { d.Name }).ToList();
        List<DummyContainer> fullDummies = smallDummies.Select(Mapper.Map<DummyContainer>).ToList();

        Debugger.Break();
    }
}

class DummyContainer
{
    public string Name { get; set; }
    public string Description { get; set; }
    public ICollection<int> DummyNumbers { get; set; }
    public FooThingy Foo { get; set; }
}

class FooThingy
{
    public string Title { get; set; }
}

Getting this exception:

Missing type map configuration or unsupported mapping.

Mapping types:
<>f__AnonymousType0`1 -> DummyContainer
<>f__AnonymousType0`1[[System.String, mscorlib, Version=4.0.0.0,  Culture=neutral, PublicKeyToken=b77a5c561934e089]] -> AutoMapperWithGenerics.DummyContainer

Destination path:
DummyContainer

Source value:
{ Name = First }

I'm bit stuck here, because documentation states that AutoMapper uses property names to map back to object: Dynamic and ExpandoObject Mapping.

Please note that code above is example. In my application, things get bit crazy as I'm actually using generics, e.g.

Mapper.Map<TEntity>

... and it should stay this way - I don't know what entity type is used. My expectation is just: map properties to existing type, if missing, set default(T).


Edit: I tried to specify mapper from dynamic to T, almost full code here:

class Program
{
    static void Main(string[] args)
    {
        // ...

        var dumminator = new DummyService();
        IEnumerable<DummyContainer> bigDummies = dumminator.GetDummies<DummyContainer>(smallDummies);

        Debugger.Break();
    }
}

class DummyService
{
    public IEnumerable<T> GetDummies<T>(IEnumerable<dynamic> dummies)
    {
        var config = new MapperConfiguration(c => c.CreateMap<dynamic, T>());
        IMapper mapper = config.CreateMapper();

        return dummies.Select(mapper.Map<T>).ToList();
    }
}

... this won't die on exception, however result is desperately empty (all properties have default value.


Solution

  • You need to use Mapper.DynamicMap<T> instead of Mapper.Map<T> to map from dynamic or anonymous classes

    List<DummyContainer> fullDummies = smallDummies.Select(Mapper.DynamicMap<DummyContainer>).ToList();