Automapper, mapping objects by linked association?

2019-08-29 07:34发布

Lets say I have these models

   public class Mouse
    {
        public string Cheese { get; set; }
    }

    public class Cat
    {
        public string Hairball { get; set; }
    }

    public class Dog
    {
        public string ChewyToy { get; set; }
    }

And I map a Mouse to a Cat then a Cat to a Dog:

    Mapper.CreateMap<Mouse, Cat>().ForMember(m => m.Hairball, o => o.MapFrom(src => src.Cheese));
    Mapper.CreateMap<Cat, Dog>().ForMember(m => m.ChewyToy, o => o.MapFrom(src => src.Hairball));

By extension, a Mouse should also be mapped to a Dog, right? When I try to map between the two:

    var mouse = new Mouse() { Cheese = "Eat me" };

    Dog dog = Mapper.Map<Mouse, Dog>(mouse);

I get an exception:

Trying to map App_Start.MapConfig+Mouse to App_Start.MapConfig+Dog. Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.

How do I do this with out explicitly creating a map between a Mouse to a Dog? This is a simple example of a bigger issue. I'm also open to switching frameworks such as Value Injector, Glue, etc if they support this behavior.

标签: c# AutoMapper
1条回答
Emotional °昔
2楼-- · 2019-08-29 08:12

How do I do this with out explicitly creating a map between a Mouse to a Dog?

The answer is simple: you can't.

Automapper has pretty straightforward logic for mapping objects. When you are adding new mapping:

Mapper.CreateMap<Mouse, Cat>();

New TypeMap is created and added to list of type maps. Yes, there is simple list. And each TypeMap has two properties: DestinationType and SourceType. Nothing in the middle. When you are trying to map some object, then list is simply searched for first TypeMap which has exactly same source and destination types, as specified in your mapping. It is done with following method (ConfigurationStore class is responsible for holding configured mappings):

TypeMap FindExplicitlyDefinedTypeMap(Type sourceType, Type destinationType)
{
    return this._typeMaps.FirstOrDefault<TypeMap>(x => 
               ((x.DestinationType == destinationType) && 
                (x.SourceType == sourceType)));
}

So, for your sample there will be two TypeMap objects in list, and of course none of them matches condition of DestinationType equalt to Dog and SourceType equal to Mouse.

查看更多
登录 后发表回答