как отобразить родительский класс, включая их вложенных детей - PullRequest
0 голосов
/ 15 сентября 2018

Если у меня есть два класса, как это:

1-ParentViewModel:

   public class ParentViewModel
        {
            public Guid Id { get;  set; }
            public string Name { get;  set; }
            public IList<ChildViewModel> Children { get; set; }

        }

2- ChildViewModel

public class ChildViewModel
    {
        public Guid? Id { get; set; }
        public string Name { get; set; }
        public Guid? ParentViewModelId { get;  set; }

    }

И яиметь две доменные модели, родительский эквивалент которых содержит: Icollection<Child> вместо IList<ChildViewModel>

Я хочу сопоставить модель родительского представления с родительским доменом (включая отображение дочерних элементов) и наоборот из домена впосмотреть модель с вложенными детьми?

1 Ответ

0 голосов
/ 16 сентября 2018

Вы всегда можете просто вручную / утомительно отобразить свойства, но, если вы хотите более общее решение, вы можете использовать отражение для сопоставления свойств по имени и обработки специального случая для коллекций.

* Примечание: 1. Это не удастся для свойств, которые являются типами коллекции интерфейсов, но вы можете немного изменить код, чтобы справиться с этим. 2. Обработка ошибок не была добавлена 3. Это пытается сопоставить свойства по имени, поэтому класс домена и класс модели представления должны иметь одинаковые имена проп. 4. Он пропустит свойства, которые он не находит в классе назначения

public class ObjectMapper
{

    public void MapObject(object source, object destination)
    {

        var srcType = source.GetType();//get source type
        var srcProps = srcType.GetProperties();//get src props, supply appropriate binding flags
        var destType = destination.GetType();//get dest type
        var destProps = destType.GetProperties();//get dest props, supply appropriate binding flags

        foreach (var prop in srcProps)
        {
            //find corresponding prop on dest obj
            var destProp = destProps.FirstOrDefault(p => p.Name == prop.Name);
            //only map if found on dest obj
            if (destProp != null)
            {
                //get src value
                var srcVal = prop.GetValue(source);
                //get src prop type
                var propType = prop.PropertyType;
                //get dest prop type
                var destPropType = destProp.PropertyType;

                //special case for collections
                if (typeof(IList).IsAssignableFrom(propType))
                {
                    //instantiate dest collection
                    var newCollection = (IList)Activator.CreateInstance(destPropType);
                    //get source collection
                    var collection = (IList)srcVal;
                    //get dest collection element type
                    var elementType = destPropType.GetGenericArguments().FirstOrDefault();

                    //iterate collection
                    foreach (var element in collection)
                    {
                        //instantiate element type 
                        var tempElement = Activator.CreateInstance(elementType);
                        //call map object on each element
                        MapObject(source: element, destination: tempElement);
                        //add mapped object to new collection
                        newCollection.Add(tempElement);
                    }

                    //set dest object prop to collection
                    destProp.SetValue(destination, newCollection);
                }
                else
                {
                    destProp.SetValue(destination, srcVal);
                }
            }
        }
    }

}
...