C# 使用AutoMapper将子类与父类映射到构造函数中

C# 使用AutoMapper将子类与父类映射到构造函数中,c#,parent-child,automapper,constructor-injection,C#,Parent Child,Automapper,Constructor Injection,我的班级结构如下: class SrcChild { public bool SomeProperty { get; set; } } class SrcParent { public IEnumerable<SrcChild> Children { get; set; } } 类SrcChild { 公共布尔SomeProperty{get;set;} } 类SrcParent { 公共IEnumerable子项{get;set;} } 因此SrcParent

我的班级结构如下:

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

class SrcParent
{
    public IEnumerable<SrcChild> Children { get; set; }
}
类SrcChild
{
公共布尔SomeProperty{get;set;}
}
类SrcParent
{
公共IEnumerable子项{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; }
}
class子类
{
公共布尔SomeProperty{get;set;}
公共DST子级(DST父级)
{
如果(父项==null)
抛出新ArgumentNullException();
}
}
类父类
{
公共IEnumerable子项{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();
    }
}
类程序
{
静态void Main(字符串[]参数)
{
/*映射配置*/
Mapper.CreateMap()
.施工(
resolutionContext=>new DstChild((DstParent)resolutionContext.Parent.DestinationValue));
CreateMap();
/*具有两个子对象的源父对象*/
var srcParent=新的srcParent
{
Children=new[]{new SrcChild(),new SrcChild()}
};
/*抛出异常*/
var dstParent=Mapper.Map(srcParent);
Console.ReadKey();
}
}
这里的主要部分是AutoMapper配置,我试图从映射上下文中提取对生成的DSTPrent的引用。这不起作用(DstParent)resolutionContext.Parent.DestinationValue为null),但我可能完全忽略了一点

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

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();
    }
}
类程序
{
/*应该为父项、子项产生价值*/
私有静态IEnumerable生成子项(SrcParent src/*,DstParent DstParent*/)
{
var result=新列表();
//结果.添加(新DstChild(DSTPRENT));
返回结果;
}
静态void Main(字符串[]参数)
{
/*映射配置*/
CreateMap();
Mapper.CreateMap()
.FormMember(dst=>dst.Children,
opt=>opt.MapFrom(src=>MakeChildren(src/*,如何在此处获取对目标的引用?*/);
/*具有两个子对象的源父对象*/
var srcParent=新的srcParent
{
Children=new[]{new SrcChild(),new SrcChild()}
};
var dstParent=Mapper.Map(srcParent);
Console.ReadKey();
}
}
但我不知道如何(如果可能的话)获取对映射器生成的DSTPRENT对象的引用


有没有人知道如何做到这一点,或者我更应该考虑放弃这个设计,去掉父引用?提前感谢。

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

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();
    }
}
类程序
{
静态IEnumerable MakeChildren(IEnumerable srcChildren,DSTPRENT DSTPRENT)
{
var dstChildren=新列表();
foreach(SrcChild中的SrcChild)
{
var dstChild=新dstChild(DSTPRENT);
Mapper.Map(child,dstChild);
dstChildren.Add(dstChildren);
}
归还儿童;
}
静态void Main(字符串[]参数)
{
CreateMap();
Mapper.CreateMap()
/*创建父对象时忽略子对象属性*/
.FormMember(dst=>dst.Children,opt=>opt.Ignore())
/*映射完成后,填充Children属性*/
.AfterMap((srcParent,dstParent)=>
{
dstParent.Children=MakeChildren(srcParent.Children,dstParent);
});
var source=新的srcpent
{
儿童=新[]
{
新的SrcChild(){SomeProperty=true},
新的SrcChild(){SomeProperty=false}
}
};
var destination=Mapper.Map(源);
Console.ReadKey();
}
}
目标已初始化子项,并由AutoMapper正确分配SomeProperty。如果你找到一个更好的解决方案,请告诉我