代码之家  ›  专栏  ›  技术社区  ›  Mateusz Przybylek

递归搜索由属性修饰的类中的属性

  •  1
  • Mateusz Przybylek  · 技术社区  · 7 年前

    我希望用属性aggregateAuthorizeIdentifier修饰所有属性。它是核心功能,所以应该尽可能快。

    我可以通过所有属性反复搜索,但我会检查所有系统和第三方libs。但这不是最佳解决方案。

    你遇到这样的问题了吗?

    public class ReadOrderHistoryQuery
    {
        public List<string> Ordering { get; set; }
    
        public Criteria Criteria { get; set; }
    
        public class Criteria
        {
            [AggregateAuthorizeIdentifier]
            public int UserId { get; set; }
    
            public string InvoiceId { get; set; }
        }
    }
    

    我的解决方案:

        static IEnumerable<PropertyWithAttribute> GetAuthorizeIdentifierAttribute(object command)
        {
            var attributedProperties = GetAuthorizeIdentifierAttribute(command.GetType());
            return attributedProperties;
        }
        static IEnumerable<PropertyWithAttribute> GetAuthorizeIdentifierAttribute(Type type)
        {
            //check current property
            var result = type.GetProperties()
                .Where(prop => Attribute.IsDefined(prop, typeof(AggregateAuthorizeIdentifierAttribute)))
                .Select(p => new PropertyWithAttribute()
                {
                    Property = p,
                    Attribute = p.GetCustomAttribute<AggregateAuthorizeIdentifierAttribute>(true)
                })
                .ToList();
            //deeper check all properties
            result.AddRange(type.GetProperties()
                .SelectMany(p => GetAuthorizeIdentifierAttribute(p.PropertyType)));
            return result;
        }
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   Mateusz Przybylek    7 年前

    Finnaly我用附加的类型选择器(通过字符串)实现了它。

        const string PropertyTypeStartWithSelector = "Diabdis.";
    
        static IEnumerable<PropertyWithAttribute> GetAuthorizeIdentifierAttribute(Type type, string propertyPathPrefix)
        {
            var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            //check current property
            var result = properties
                .Where(prop => Attribute.IsDefined(prop, typeof(AggregateAuthorizeIdentifierAttribute)))
                .Select(p => new PropertyWithAttribute()
                {
                    PropertyPath = propertyPathPrefix == null ? p.Name : $"{propertyPathPrefix}{PropertyPathSeparator}{p.Name}",
                    Attribute = p.GetCustomAttribute<AggregateAuthorizeIdentifierAttribute>(true)
                })
                .ToList();
    
            //check deeper properties, BUT just selector classes
            result.AddRange(properties
                .Where(p => p.DeclaringType.FullName.StartsWith(PropertyTypeStartWithSelector))
                .SelectMany(p => GetAuthorizeIdentifierAttribute(p.PropertyType, propertyPathPrefix == null ? p.Name : $"{propertyPathPrefix}{PropertyPathSeparator}{p.Name}")));
            return result;
        }
    
        2
  •  0
  •   0xTheOldOne Fabio Luz    7 年前

    当我需要做那样的事情时,我总是这样做:

    object objectToSearch = ...
    
    PropertyInfo[] properties = objectToSearch.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
    if (properties != null && properties.Length > 0)
    {
        properties.ToList().ForEach(p =>
        {
            if (p.GetCustomAttributes(typeof(AggregateAuthorizeIdentifierAttribute), false).Count() == 1)
            {
                // Do something with the property
            }
        });
    }
    

    因此,您可以使用扩展方法返回具有特定属性的对象的所有属性。