我正在使用 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
。然后,对于 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;
}
最佳答案
我刚刚运行了您的代码,它按预期工作。但是,也许困扰您的是 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/