public static IEnumerable <IModelValueMemberInfo> GetCompatibleModelValueMembers(TypeInfo type,
                                                                                         Func <PropertyInfo, bool> propertySelector = null, Func <FieldInfo, bool> fieldSelector = null)
        {
            var members = new ModelMemberInfoCollection <IModelValueMemberInfo>(
                GetCompatiblePropertyInfos(type, propertySelector).Select(x => new ModelPropertyInfo(x)));

            members.AddRange(GetCompatibleFieldInfos(type, fieldSelector).Select(x => new ModelFieldInfo(x)));

            var result = OrderMemberInfos(members);

            return(result);
        }
示例#2
0
        public static IEnumerable <T> OrderMemberInfos <T>(IEnumerable <T> collection) where T : IModelMemberInfo
        {
            if (collection == null)
            {
                throw new ArgumentNullException(nameof(collection));
            }

            var collectionToList = collection.ToList();

            var mustOrder = new List <Tuple <T, ModelMemberOrderAttribute> >(collectionToList.Count);
            var result    = new ModelMemberInfoCollection <T>();

            foreach (var element in collectionToList)
            {
                var attr = element.GetCustomAttributes(typeof(ModelMemberOrderAttribute), true);
                if (attr != null && attr.Any())
                {
                    mustOrder.Add(new Tuple <T, ModelMemberOrderAttribute>
                                      (element, attr.First() as ModelMemberOrderAttribute));
                }
                else
                {
                    result.Add(element);
                }
            }

            var insertAfters = new List <Tuple <T, ModelMemberOrderAttribute> >(mustOrder.Count);

            foreach (var order in mustOrder)
            {
                var member = order.Item1;
                var attr   = order.Item2;
                if (attr is ModelMemberOrderInsertBeforeAttribute)
                {
                    insertAfters.Add(order);
                    continue;
                }

                var index = attr.Order;
                if (index == -1)
                {
                    result.Add(member);
                }
                else
                {
                    result.Insert(index, member);
                }
            }

            bool oneInserted = true;

            while (oneInserted && insertAfters.Any())
            {
                oneInserted = false;
                var inserts = insertAfters.ToArray();
                foreach (var order in inserts)
                {
                    var member = order.Item1;
                    var attr   = order.Item2 as ModelMemberOrderInsertBeforeAttribute;
                    if (attr == null)
                    {
                        continue;
                    }
                    var index = result.SequentialIndexOf(x => attr.NameComparer.Equals(x.Name, attr.MemberName));
                    if (index >= 0)
                    {
                        insertAfters.Remove(order);
                        result.Insert(index, member);
                        oneInserted = true;
                    }
                }
            }
            if (insertAfters.Any())
            {
                result.AddRange(insertAfters.Select(x => x.Item1));
            }

            return(result);
        }