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); }