【问题标题】:Mapping child classes with parent injected in the constructor using AutoMapper使用 AutoMapper 将子类与在构造函数中注入的父类映射
【发布时间】:2015-12-15 22:16:16
【问题描述】:

我有以下类结构:

class SrcChild
{
    public bool SomeProperty { get; set; }
}

class SrcParent
{
    public IEnumerable<SrcChild> Children { get; set; }
}

所以 SrcParent 有一个 SrcChild 对象的集合。

现在我想将 SrcParent 的一个实例映射到 DstParent。以下是目标类:

class DstChild
{
    public bool SomeProperty { get; set; }

    public DstChild(DstParent parent)
    {
        if (parent == null)
            throw new ArgumentNullException();
    }
}

class DstParent
{
    public IEnumerable<DstChild> Children { get; set; }
}

DstParent 有一个 DstChild 对象的集合,这些对象使用构造函数注入来保持对其父级的引用。

使用 AutoMapper,我尝试了以下操作:

class Program
{
    static void Main(string[] args)
    {
        /* mapping configuration */
        Mapper.CreateMap<SrcChild, DstChild>()
            .ConstructUsing(
                resolutionContext => new DstChild((DstParent)resolutionContext.Parent.DestinationValue));
        Mapper.CreateMap<SrcParent, DstParent>();

        /* source parent object with two children */
        var srcParent = new SrcParent
        {
            Children = new[] { new SrcChild(), new SrcChild() }
        };

        /* throws an exception */
        var dstParent = Mapper.Map<DstParent>(srcParent);

        Console.ReadKey();
    }
}

这里的主要部分是 AutoMapper 配置,我试图从映射上下文中提取对生成的 DstParent 的引用。这不起作用((DstParent)resolutionContext.Parent.DestinationValue 为空),但也许我在这里完全错过了一点?

我的另一个想法是使用函数来创建子值,如下所示:

class Program
{
    /* Should produce value for DstParent.Children */
    private static IEnumerable<DstChild> MakeChildren(SrcParent src /*, DstParent dstParent */)
    {
        var result = new List<DstChild>();
        // result.Add(new DstChild(dstParent));
        return result;
    }

    static void Main(string[] args)
    {
        /* mapping configuration */
        Mapper.CreateMap<SrcChild, DstChild>();
        Mapper.CreateMap<SrcParent, DstParent>()
            .ForMember(dst => dst.Children,
                opt => opt.MapFrom(src => MakeChildren(src /*, How to obtain a reference to the destination here? */)));

        /* source parent object with two children */
        var srcParent = new SrcParent
        {
            Children = new[] { new SrcChild(), new SrcChild() }
        };

        var dstParent = Mapper.Map<DstParent>(srcParent);

        Console.ReadKey();
    }
}

但我不知道如何(如果可能的话)获取对 Mapper 生成的 DstParent 对象的引用。

有没有人知道如何做到这一点,或者我应该考虑完全放弃这个设计并摆脱父参考?提前致谢。

【问题讨论】:

    标签: c# parent-child automapper constructor-injection


    【解决方案1】:

    好的,我发现的一个解决方案并不漂亮,但它确实有效:

    class Program
    {
        static IEnumerable<DstChild> MakeChildren(IEnumerable<SrcChild> srcChildren, DstParent dstParent)
        {
            var dstChildren = new List<DstChild>();
            foreach (SrcChild child in srcChildren)
            {
                var dstChild = new DstChild(dstParent);
                Mapper.Map(child, dstChild);
                dstChildren.Add(dstChild);
            }
            return dstChildren;
        }
    
        static void Main(string[] args)
        {
            Mapper.CreateMap<SrcChild, DstChild>();
            Mapper.CreateMap<SrcParent, DstParent>()
                /* Ignore Children property when creating DstParent*/
                .ForMember(dst => dst.Children, opt => opt.Ignore())
                /* After mapping is complete, populate the Children property */
                .AfterMap((srcParent, dstParent) =>
                {
                    dstParent.Children = MakeChildren(srcParent.Children, dstParent);
                });
    
            var source = new SrcParent
            {
                Children = new[]
                {
                    new SrcChild() {SomeProperty = true},
                    new SrcChild() {SomeProperty = false}
                }
            };
    
            var destination = Mapper.Map<DstParent>(source);
    
            Console.ReadKey();
        }
    }
    

    目标已初始化子项,AutoMapper 正确分配了 SomeProperty。如果您找到更好的解决方案,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-01
      • 2018-02-28
      相关资源
      最近更新 更多