/// <summary> /// Returns /// </summary> /// <param name="item">Item to generate hash on</param> /// <param name="filters">A string array that lets you specify wild cards or '-' to remove blocks of fields. Lets assume a class that contains properties KeyFieldA, KeyFieldB, DataFieldA, DataFieldB, DataFieldC /// For Example: ["-Key*"] - This says include all fields but ignore all fields that begin with Key - The Hash will be generated from - DataFieldA, DataFieldB, DataFieldC</param> /// ["Key*", "DataFieldA"] - Include all fields that begin with Key and the field DataFieldA - The Hash will be generated from - KeyFieldA, KeyFieldB, DataFieldA</param> /// ["*Field*", "-Data*"] - Include all fields that have the text 'Field' in the middle but ignoring all fields that begin with Data - The Hash will be generated from - KeyFieldA, KeyFieldB</param> /// <typeparam name="T">List of members filtered by filter</typeparam> /// <returns></returns> internal static TypeMemberIndex Members <T>(this T item, string[] filters) { var targetIndexMembers = new TypeMemberIndex(); if (!IndexMembers.ContainsKey(typeof(T).Name)) { var targetAccessor = TypeAccessor.Create(typeof(T)); if (!IndexMembers.ContainsKey(typeof(T).Name)) { var members = targetAccessor.GetMembers(); foreach (var _item in members) { targetIndexMembers.Add(_item.Name, _item); } IndexMembers.Add(typeof(T).Name, targetIndexMembers); } } targetIndexMembers = IndexMembers[typeof(T).Name]; if (filters.Length > 0) { var targetIndexMembersFiltered = new TypeMemberIndex(); /* If we start with an not operator, then we will assume we want every column */ var allColumnOperator = filters.First().StartsWith("-"); var keepField = allColumnOperator; foreach (var _targetFieldName in targetIndexMembers.Keys) { var targetFieldName = _targetFieldName; if (allColumnOperator) { keepField = (targetFieldName.IsIn(filters)); } else { if (targetFieldName.IsIn(filters)) { keepField = true; } } if (keepField) { targetIndexMembersFiltered.Add(targetFieldName, targetIndexMembers[targetFieldName]); } } targetIndexMembers = targetIndexMembersFiltered; } return(targetIndexMembers); }
internal static T As <S, T>(this S item, TypeMemberIndex sourceIndexMembers, TypeMemberIndex targetIndexMembers, TypeAccessor sourceAccessor, TypeAccessor targetAccessor) where T : new() { T targetItem = new T(); foreach (var targetFieldName in targetIndexMembers.Keys) { try { if (sourceIndexMembers.ContainsKey(targetFieldName)) { var sourcePropertyType = sourceIndexMembers[targetFieldName].Type; sourcePropertyType = ((sourcePropertyType.Name.Contains("Nullable")) ? sourcePropertyType.GenericTypeArguments.First() : sourcePropertyType); var targetPropertyType = targetIndexMembers[targetFieldName].Type; var isTargetNullable = targetPropertyType.Name.Contains("Nullable"); targetPropertyType = ((isTargetNullable) ? targetPropertyType.GenericTypeArguments.First() : targetPropertyType); object sourceValue = sourceAccessor[item, targetFieldName]; var bForceSpecified = false; if (sourceValue != null) { if ((targetPropertyType.Name.Equals("DateTime")) && (sourceValue.Equals(DateTime.Parse("1/1/0001 12:00:00 AM")))) { sourceValue = null; } else if ((targetPropertyType.Name.Equals("DateTime")) && (sourceValue.Equals(DateTime.MaxValue))) { sourceValue = null; bForceSpecified = true; } else if ((sourcePropertyType.IsEnum) && (targetPropertyType.Name.Contains("String"))) { sourceValue = sourceValue?.ToString(); } else if ((sourcePropertyType.Name.Contains("String")) && (targetPropertyType.IsEnum)) { sourceValue = Enum.Parse(targetPropertyType, sourceValue?.ToString()); } } if ((sourceValue == null) || (sourceValue.Equals("DBNull"))) { if ((targetPropertyType.Name.Equals("DateTime") && (!isTargetNullable))) { targetAccessor[targetItem, targetFieldName] = DateTime.Parse("1/1/0001 12:00:00 AM"); } else { if (isTargetNullable) { targetAccessor[targetItem, targetFieldName] = null; } } } else if ((targetPropertyType.FullName == sourcePropertyType.FullName) || (targetPropertyType.Name.Equals(sourceValue.GetType().Name))) { targetAccessor[targetItem, targetFieldName] = sourceValue; } else { if (targetPropertyType.GenericTypeArguments.Contains(targetPropertyType)) { targetAccessor[targetItem, targetFieldName] = sourceValue; } else { var c = TypeDescriptor.GetConverter(targetPropertyType); if (c.CanConvertTo(targetPropertyType)) { targetAccessor[targetItem, targetFieldName] = c.ConvertTo(sourceValue, targetPropertyType); } else { try { targetAccessor[targetItem, targetFieldName] = System.Convert.ChangeType(sourceValue, targetPropertyType); } catch (System.Exception ex) { throw new System.Exception(string.Format("Could not convert field {0} of type {1} to {2}", targetFieldName, sourceIndexMembers[targetFieldName].Type.Name, targetPropertyType.Name), ex); } } } } if (targetIndexMembers.ContainsKey(targetFieldName + "Specified")) { try { targetAccessor[targetItem, targetFieldName + "Specified"] = ((sourceValue != null) || bForceSpecified); } catch (Exception ex) { var message = string.Format("Unable to set {0}Specified as {1}. {2}", targetFieldName + "Specified", targetPropertyType.Name, ex.Message); throw new Exception(message, ex); } } } } catch (Exception exField) { var message = string.Format("Unable to set {0}. {1}", targetFieldName, exField.Message); throw new Exception(message, exField); } } return(targetItem); }