AutoMapper pass parent reference when mapping child object

谁说胖子不能爱 提交于 2019-12-10 14:32:14

问题


I am trying to use AutoMapper to map some DTO (data contract) objects received from a web service into my business objects. The root DTO object contains a collection of child objects. My business object also has a child collection of child business objects. In order to get AutoMapper to work, I had to include a setter on the collection property in my business object or the collection would always be empty. In addition, I had to add a default constructor to the collection type. So, it appears to me that AutoMapper is instantiating a new collection object, populating it and setting as the collection property of my business object.

While this is all well and good, I have additional logic that has to be wired up when the collection is created and having the default constructor defeats the purpose. Essentially, I am establishing the parent-child relationship and wiring up some events so they bubble from child to parent.

What I would like to do is to have AutoMapper simply map the child objects from the DTO's collection to the existing collection on my BO. In other words, skip creating a new collection and simply use the one the business object already has.

Is there any way to easily accomplish this?!?!?

UPDATE

Perhaps a better question, and simpler solution to my problem, is if it is possible to define arguments that AutoMapper will pass to the collection when instantiated? My child collection is defined like this:

public class ChildCollection : Collection<ChildObjects>
{
    public ChildCollection(ParentObject parent) { Parent = parent; }
}

If I can configure AutoMapper to use this constructor and pass in the proper object, that would be PERFECT!

ANOTHER UPDATE

For the sake of clarity, here are the other classes in the problem space:

public class ParentObject
{
    private ChildCollection _children;

    public ChildCollection Children
    {
        get
        {
            if (_children == null) _children = new ChildCollection(this);

            return _children;
        }
    }
}

public class ParentDTO
{
    public ICollection<ChildDTO> Children { get; set; }
}

public class ChildDTO
{
    public String SomeProperty { get; set; }
}

I configure AutoMapper this way:

Mapper.CreateMap<ParentDTO, ParentObject>();
Mapper.CreateMap<ChildDTO, ChildObject>();

Doing so this way and I have to add a setter to the Children property in ParentObject and a default (parameterless) constructor to ChildCollection. While I can work around the need to define the parent-child relationship, it seems that it would be logical to expect AutoMapper to support configuring the map to use a specific constructor when creating the child collection. Something like this:

Mapper.CreateMap<ParentDTO, ParentObject>()
    .ForMember(obj => obj.Children, opt.MapFrom(dto => dto.Children))
    .ConstructUsing(col => new ChildCollection(obj));

Notice that I am passing in the reference to "obj" which is the ParentObject instance being mapped.


回答1:


It turns out that the answer was right there all along. The UseDestinationValue option does exactly what I want.

This options instructs AutoMapper to use the existing property on the target object and map any child properties or collection items into that object rather than creating a new proxy object.

So, here's all I have to do in my application:

Mapper.CreateMap<ParentDTO, ParentObject>()
    .ForMember(obj => obj.Children,
           opt.UseDestinationValue());

And, voila! Now I can instantiate the child collection, with parent reference, and setup the reference back to the parent in each item as it is added to the collection.




回答2:


If I understood your problem, you should be able to use ConstructUsing as stated in this answer: Automapper - how to map to constructor parameters instead of property setters



来源:https://stackoverflow.com/questions/5341523/automapper-pass-parent-reference-when-mapping-child-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!