使用AutoMapper对特定属性进行自定义转换

Sig*_*hol 3 list automapper collectionbase

亲爱的互联网社区.

我需要将元素从一个对象映射到另一个对象.这些类是相同的(相同的类名,相同的属性),所以我认为我们应该尝试使用AutoMapper.它似乎工作得很好,但我遇到了障碍:一个类有一个object类型属性,用作一种"外卡"容器.

public class MyPet
{
    public int Id { get; set; }
    public object Pet{ get; set; }
}

public class Cat
{

}

public class Dog
{

}
Run Code Online (Sandbox Code Playgroud)

我初步认为AutoMapper能够识别实例的类型并按照指示执行适当的映射:

Mapper.CreateMap<LocalService.MyPet, ExternalService.MyPet>();
Mapper.CreateMap<LocalService.Cat, ExternalService.Cat>();
Mapper.CreateMap<LocalService.Dog, ExternalService.Dog>();


var dtoWithCat0 = new LocalService.MyPet()
{
    Id = 1,
    Item = new LocalService.Cat()
};

var dtoWithDog0 = new LocalService.MyPet()
{
    Id = 2,
    Item = new LocalService.Dog()
};

var dtoWithCat1 = Mapper.Map<ExternalService.MyPet>(dtoWithCat0);

var dtoWithDog1 = Mapper.Map<ExternalService.MyPet>(dtoWithDog0);

Console.WriteLine("{0}: {1} - {2}", dtoWithCat1.GetType().FullName, dtoWithCat1.Id, dtoWithCat1.Item.GetType().FullName);

Console.WriteLine("{0}: {1} - {2}", dtoWithCat1.GetType().FullName, dtoWithDog1.Id, dtoWithDog1.Item.GetType().FullName);
Run Code Online (Sandbox Code Playgroud)

但是,这是输出:

ExternalService.MyPet: 1 - LocalService.Cat
ExternalService.MyPet: 2 - LocalService.Dog
Run Code Online (Sandbox Code Playgroud)

如您所见,AutoMapper很乐意复制属性的对象引用,Item而不是创建新的ExternalService实例.

我正在寻找一种方法来指示AutoMapper Item根据自定义函数解析属性,如下所示:

object ConvertPet(object source)
{
    if (source is LocalService.Cat) return Mapper.Map<ExternalService.Cat>(source as LocalService.Cat);
    if (source is LocalService.Dog) return Mapper.Map<ExternalService.Dog>(source as LocalService.Dog);
}
Run Code Online (Sandbox Code Playgroud)

任何提示将不胜感激!

-S

PS.我注意到存在一种ConvertUsing方法.不幸的是,这似乎用自定义显式映射替换了AutoMapper的"自动"部分,需要实现DTO上所有属性的映射.我想懒得让AutoMapper为这个单一属性做一个例外......

小智 6

可能MapFrom会帮助你

例如

 Mapper.CreateMap<LocalService.MyPet, ExternalService.MyPet>()
            .ForMember(dest => dest.MyPet,
                        opt => opt.MapFrom(
                        src => ConvertPet(src.MyPet)));
Run Code Online (Sandbox Code Playgroud)