How to configure Automapper to automatically ignore properties with ReadOnly attribute?

后端 未结 3 545
感情败类
感情败类 2020-12-09 16:04

Context:

Let\'s say I have the following \"destination\" class:

public class Destination
{
    public String WritableProperty { get; set; }

    pu         


        
相关标签:
3条回答
  • 2020-12-09 16:36

    Write Extension Method as shown below:

    public static class IgnoreReadOnlyExtensions
    {
        public static IMappingExpression<TSource, TDestination> IgnoreReadOnly<TSource, TDestination>(
                   this IMappingExpression<TSource, TDestination> expression)
        {
            var sourceType = typeof(TSource);
    
            foreach (var property in sourceType.GetProperties())
            {
                PropertyDescriptor descriptor = TypeDescriptor.GetProperties(sourceType)[property.Name];
                ReadOnlyAttribute attribute = (ReadOnlyAttribute) descriptor.Attributes[typeof(ReadOnlyAttribute)];
                if(attribute.IsReadOnly == true)
                    expression.ForMember(property.Name, opt => opt.Ignore());
            }
            return expression;
        }
    }
    

    To call extension method:

    Mapper.CreateMap<ViewModel, DomainModel>().IgnoreReadOnly();

    0 讨论(0)
  • 2020-12-09 16:50

    Now you could also use ForAllPropertyMaps to disable it globally:

    configure.ForAllPropertyMaps(map =>
        map.SourceMember.GetCustomAttributes().OfType<ReadOnlyAttribute>().Any(x => x.IsReadOnly),
        (map, configuration) =>
        {
            configuration.Ignore();
        });
    
    0 讨论(0)
  • 2020-12-09 16:51

    If you wanted to only map properties that have a certain attribute, in my case the [DataMember] attribute, I wrote a method based on the excellent reply above to handle this for both the source and destination:

    public static class ClaimMappingExtensions
    {
        public static IMappingExpression<TSource, TDestination> IgnoreAllButMembersWithDataMemberAttribute<TSource, TDestination>(
                   this IMappingExpression<TSource, TDestination> expression)
        {
            var sourceType = typeof(TSource);
            var destinationType = typeof(TDestination);
    
            foreach (var property in sourceType.GetProperties())
            {
                var descriptor = TypeDescriptor.GetProperties(sourceType)[property.Name];
                var hasDataMemberAttribute = descriptor.Attributes.OfType<DataMemberAttribute>().Any();
                if (!hasDataMemberAttribute)
                    expression.ForSourceMember(property.Name, opt => opt.Ignore());
            }
    
            foreach (var property in destinationType.GetProperties())
            {
                var descriptor = TypeDescriptor.GetProperties(destinationType)[property.Name];
                var hasDataMemberAttribute = descriptor.Attributes.OfType<DataMemberAttribute>().Any();
                if (!hasDataMemberAttribute)
                    expression.ForMember(property.Name, opt => opt.Ignore());
            }
    
            return expression;
        }
    }
    

    It will be called as the other method did:

    Mapper.CreateMap<ViewModel,DomainModel>().IgnoreAllButMembersWithDataMemberAttribute();
    
    0 讨论(0)
提交回复
热议问题