コード例 #1
0
ファイル: Builder.cs プロジェクト: Fedorm/core-master
        static bool TryBuildMembers <T>(string str
                                        , ExpressionFactory factory
                                        , Type baseType
                                        , object baseObject
                                        , out IExpression <T> result)
        {
            result = null;
            MemberExpression <T> block = new MemberExpression <T>(str);

            string[] members = str.Split('.');

            for (int i = 0; i < members.Length; i++)
            {
                string member = members[i].Trim();

                if (i == 0 && baseType.GetInterfaces().Contains(typeof(IDbRecordset)))
                {
                    block.Add(new DataReaderMember(member, member));
                    baseType = typeof(object);
                    continue;
                }

                if (baseType == typeof(DbRef))
                {
                    block.Add(new DbRefMember(member, member));
                    baseType = typeof(object);
                    continue;
                }

                if (baseType == typeof(IDbRef))
                {
                    block.Add(new DbRefMember(member, member));
                    baseType = typeof(object);
                    continue;
                }

                if (member.Contains('(') && member.Last() == ')')
                {
                    string[] details = member.Split('(', ')');

                    IExpression <object>[] p = ParseMethodParameters(factory, details);

                    // Check helper
                    MethodInfo helperMI = typeof(Helper).GetMethod(details[0]);
                    if (helperMI != null)
                    {
                        block.Add(new HelperMember(helperMI, p, member));
                        baseType = helperMI.ReturnType;
                    }
                    else
                    {
                        MethodInfo mi = baseType.GetMethod(details[0]);
                        if (mi != null)
                        {
                            block.Add(new MethodMember(mi, p, details[0]));
                            baseType = mi.ReturnType;
                        }
                        else
                        {
                            return(false);
                        }
                    }
                }
                else if (member.Contains('[') && member.Last() == ']')
                {
                    // TODO: ¬крутить парсинг индексаторов
                    throw new NotSupportedException("Indexers are not supported :_(");
                }
                else
                {
                    // Check helper
                    MethodInfo helperMI = typeof(Helper).GetMethod(member);
                    if (helperMI != null)
                    {
                        block.Add(new HelperMember(helperMI, new IExpression <object> [0], member));
                        baseType = helperMI.ReturnType;
                    }
                    else
                    {
                        if (baseObject is IEntity)
                        {
                            block.Add(new EntityMember(member));
                            baseType = typeof(object);
                        }
                        else
                        {
                            string       property = members[i].Trim();
                            PropertyInfo pi       = baseType.GetProperty(property);
                            if (pi != null)
                            {
                                block.Add(new PropertyMember(pi, member));

                                baseType = pi.PropertyType;
                            }
                            else
                            {
                                // Dirty hack ("workflow.order")
                                if (baseType != null &&
                                    (baseType.ToString().Contains("BitMobile.ValueStack.CustomDictionary") ||
                                     baseType.ToString().Contains("BitMobile.DbEngine.DbRef")))
                                {
                                    MethodInfo mi        = baseType.GetMethod("GetValue");
                                    object     itemValue = mi.Invoke(baseObject, new object[] { member });

                                    block.Add(new ValueMember(itemValue, member));

                                    if (itemValue != null)
                                    {
                                        baseType = itemValue.GetType();
                                    }
                                    else
                                    {
                                        baseType = typeof(object);
                                    }
                                }
                                else
                                {
                                    return(false);
                                }
                            }
                        }
                    }
                }
            }

            result = block;
            return(true);
        }