尝试使用AutoMapper映射ImmutableDictionary时出错

时间:2016-06-14 02:49:20

标签: c# .net automapper immutable-collections

我想将POCO映射到ImmutableDictionary<string, object>,而Automapper会引发异常,因为Add不支持ImmutableDictionary操作。

POCO对象位于源类型中名为Data的属性中,该属性将映射到目标中的DataBag属性。目前尚不知道Data的类型。

我正在使用此映射:

var t = new MapperConfiguration(cfg =>
                    cfg.CreateMap(@event.GetType(), typeof(StoredEvent))
                       .ForMember("DataBag", opt => opt.MapFrom("Data")));

并收到此错误:

Mapping types:
Dictionary`2 -> ImmutableDictionary`2
System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] -> System.Collections.Immutable.ImmutableDictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

Destination path:
StoredEvent.DataBag.DataBag.DataBag

为了解决这个问题,我尝试使用自定义解析器:

public class ImmutableDictionaryResolver : IValueResolver
{
    public ResolutionResult Resolve(ResolutionResult source)
    {
        var dictionary = Mapper.Map<Dictionary<string, object>>(source.Value);
        return source.New(dictionary.ToImmutableDictionary());
    }
}

使用此映射:

var t = new MapperConfiguration(cfg =>
            cfg.CreateMap(@event.GetType(), typeof(StoredEvent))
            .ForMember(nameof(StoredEvent.DataBag), opt => 
              opt.ResolveUsing<ImmutableDictionaryResolver>().FromMember("Data")));

但我仍然遇到同样的错误。在第二个例子中,它抱怨:

Mapping types:
ImmutableDictionary`2 -> ImmutableDictionary`2
System.Collections.Immutable.ImmutableDictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] -> System.Collections.Immutable.ImmutableDictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

Destination path:
StoredEvent.DataBag.DataBag

1 个答案:

答案 0 :(得分:0)

不要使用ForMember尝试使用ConstructUsing,因此您可以为不可变对象赋予值。

var t = new MapperConfiguration(cfg =>
            cfg.CreateMap(@event.GetType(), typeof(StoredEvent))
            .ConstructUsing(x => new ImmutableDictionaryResolver(...)));