Как отобразить несколько исходных элементов, чтобы propertyMap.SourceMembers дал эти несколько исходных элементов? - PullRequest
0 голосов
/ 10 ноября 2018

Я хочу повторно использовать инициализированные отображения c # Automapper (используя версию 6.2.2), просматривая все сопоставленные свойства.

Предположим, у меня есть следующее:

public class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class PersonDto
{
    public int Id { get; set; }
    public string FullName { get; set; }
}

AutoMapper.Mapper.Initialize(cfg =>
{
    cfg.CreateMap<Person, PersonDto>()
        .ForMember(dest => dest.FullName, 
                    opt => opt.MapFrom(src => src.FirstName + " " + src.LastName));
};

Цикл для Id ведет себя как ожидалось:

var map = AutoMapper.Mapper.Configuration.FindTypeMapFor<Person, PersonDto>();
foreach (var propertyMap in map.GetPropertyMaps())
{
    var destProp = propertyMap.DestinationProperty.Name; // = "Id"
    var sourceMember = propertyMap.SourceMember.Name; // = "Id"
    var sourceMembers = propertyMap.SourceMembers; // Count = 1
}

Но когда я перебираю отображение свойства FullName, я хочу добиться, чтобы propertyMap.SourceMembers приводил к двум SourceMembers FirstName и LastName:

var map = AutoMapper.Mapper.Configuration.FindTypeMapFor<Person, PersonDto>();
foreach (var propertyMap in map.GetPropertyMaps())
{
    var destProp = propertyMap.DestinationProperty.Name; // = "FullName"
    var sourceMember = propertyMap.SourceMember.Name; // = "LastName" (I don't care)
    var sourceMembers = propertyMap.SourceMembers; // Count = 0 (want to achieve 2 for FirstName and LastName)
}

Моя цель - создать автоматическое аналогичное отображение для функциональности orderBy на основе инициализированных отображений автоматического преобразователя.Так что мне нужно знать (а) порядок и (б) sourceMembers.В приведенном выше случае я хочу получить сопоставление для FullName от его исходных элементов FirstName и LastName (в этом порядке).

Можно ли как-то правильно зарегистрировать несколько исходных элементов, чтобы propertyMap.SourceMembers возвращает всех сопоставленных исходных элементов?Если да, как должна выглядеть инициализация карты?

PS: я не хочу писать сопоставления orderBy вручную, поскольку у меня уже есть сопоставления благодаря autopper.

1 Ответ

0 голосов
/ 10 ноября 2018

Благодаря Lucian Bargaoanu я разработал следующий грязный обходной путь.

Обратите внимание, что я впервые обращаюсь к интерпретации выражений, поэтому сохраните качество моего решения:

var map = AutoMapper.Mapper.Configuration.FindTypeMapFor<Person, PersonDto>();
foreach (var propertyMap in map.PropertyMaps)
{
    var destProp = propertyMap.DestinationMember.Name; // = "FullName"
    var sourceMember = propertyMap.SourceMember?.Name; // = "LastName" (I don't care)
    var sourceMembers = propertyMap.SourceMembers.ToList();
    if (sourceMembers.Count() == 0)
    {
        ResolveSourceMembersInOrder(sourceMembers,
            propertyMap.CustomMapExpression.Body as BinaryExpression);
    }

    // sourceMembers now yield the two desired sourceMembers "FirstName" and "LastName"
}

public static void ResolveSourceMembersInOrder(List<MemberInfo> memberInfos, BinaryExpression expression)
{
    if (memberInfos == null)
    {
        memberInfos = new List<MemberInfo>();
    }

    if (expression == null)
    {
        return;
    }

    var left = expression.Left;
    if (left.NodeType == ExpressionType.MemberAccess)
    {
        memberInfos.Add(MemberVisitor.GetMemberPath(left).FirstOrDefault());
    }
    else
    {
        ResolveSourceMembersInOrder(memberInfos, left as BinaryExpression);
    }

    var right = expression.Right;
    if (right.NodeType == ExpressionType.MemberAccess)
    {
        memberInfos.Add(MemberVisitor.GetMemberPath(right).FirstOrDefault());
    }
    else
    {
        ResolveSourceMembersInOrder(memberInfos, right as BinaryExpression);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...