c# - ForAllMembers 覆盖忽略已定义的规则

标签 c# automapper

我正在使用 AutoMapper,我需要忽略未定义 Attribute 的成员。然后,如果成员没有被忽略,我只需要映射定义值的地方。我设法分别实现了这两个,但是 ForAllMembers/ForAllOtherMembers 似乎覆盖了第一条规则。

假设我有这个类(class):

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

    public string IgnoreMe { get; set; }

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

无论如何,我都想忽略 IgnoreMe。然后,对于 NameDontIgnoreNumber,我只想在它们具有值时映射它们。我怎样才能做到这一点?

我试过这个:

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;
}

最佳答案

我刚刚运行了您的代码,它按预期工作。但是,也许困扰您的是 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)));
            });
        });
});

我已经使用 NuGet (8.0.0.0) 上可用的最新版本的自动映射器重新创建了您的场景。

关于c# - ForAllMembers 覆盖忽略已定义的规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55600079/

相关文章:

c# - 如果在运行任务之前创建新的表单实例,则等待任务会挂起

c# - 处理文本框中的 Shift-Enter 事件

tfs - 仅在 TFS 构建中出现 NSubstitute 参数匹配器错误

asp.net-mvc - 映射时如何处理循环引用?

c# - ProjectionTo 返回 ArgumentException : Argument types do not match

c# - 如何在封闭泛型类型上获取泛型方法,从开放泛型类型打开 MethodInfo?

c# - ProcessStartInfo 卡在 "WaitForExit"上?为什么?

c# - 如何验证 ASP.NET Core 中的 DI 容器?

c# - AutoMapper 忽略子集合属性

所有成员和所有其他成员的自动映射器链接