Переопределение ForAllMembers Игнорировать уже определенные правила - PullRequest
2 голосов
/ 09 апреля 2019

Я использую AutoMapper, и мне нужно игнорировать элементы, где Attribute не определено.Затем, если элемент не игнорируется, мне нужно отобразить только там, где определены значения.Мне удалось достичь этих двух по отдельности, но ForAllMembers / ForAllOtherMembers, кажется, переопределяет первое правило.

Допустим, у меня есть этот класс:

public class Foo
{
    [MyCustomAttribute]
    public string Name { get; set; }

    public string IgnoreMe { get; set; }

    [MyCustomAttribute]
    public int? DontIgnoreNumber { get; set; }
}

Я хочуигнорировать IgnoreMe независимо.Затем для Name и DontIgnoreNumber я хочу отобразить их, только если они имеют значение.Как мне этого добиться?

Я пробовал это:

Mapper.Initialize(cfg =>
{
    cfg.CreateMap<Foo, Foo>()
        .IgnoreAllNonAttributedEntities()
        .ForAllOtherMembers(opts =>
        {
            opts.Condition((src, dest, srcMember) =>
            {
                // Check if source is a default value
                return srcMember != null;
            });
        });
});

Я проверил, что правило ForAllOtherMembers работает.И я отдельно проверил, что IgnoreAllNonAttributedEntities работает.Когда я пытаюсь объединить их, ForAllOtherMembers, кажется, имеет приоритет.

IgnoreAllNonAttributedEntities определяется как:

public static IMappingExpression<TSource, TDestination> IgnoreAllNonAttributedEntities<TSource, TDestination>
    (this IMappingExpression<TSource, TDestination> expression)
{
    var flags = BindingFlags.Public | BindingFlags.Instance;
    //var sourceType = typeof(TSource);
    var destinationType = typeof(TDestination);

    foreach(var prop in destinationType.GetProperties(flags))
    {
        var attr = ReflectionHelpers.GetAttribute<MyCustomAttribute>(prop);
        if (attr == null)
        {
            expression.ForMember(prop.Name, opt => opt.Ignore());
        }
    }

    return expression;
}

1 Ответ

3 голосов
/ 22 апреля 2019

Я только что запустил ваш код, и он работает как положено.Однако, возможно, вас беспокоит значение по умолчанию для типов значений в c # (потому что вы проверяете только нулевые значения).Вот мое исправление для типов значений:

Mapper.Initialize(cfg =>
{
    cfg.CreateMap<Foo, Foo>()
        .IgnoreAllNonAttributedEntities()
        .ForAllOtherMembers(opts =>
        {
            opts.Condition((src, dest, srcMember) =>
            {
                var srcType = srcMember?.GetType();
                if (srcType is null)
                {
                    return false;
                }

                return (srcType.IsClass && srcMember != null)
                || (srcType.IsValueType
                && !srcMember.Equals(Activator.CreateInstance(srcType)));
            });
        });
});

Я воссоздал ваш scenerio, используя последнюю версию automapper, доступную в NuGet (8.0.0.0).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...