/AzureTableStorage/src/ApplicationSettingsManager/DynamicMethods.cs
# · C# · 469 lines · 234 code · 81 blank · 154 comment · 87 complexity · f0c7875e882c2dbf60f3180ce850b133 MD5 · raw file
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Reflection;
-
- namespace ApplicationSettingsManager
- {
- public static class DynamicObjectMethods
- {
-
- /// <summary>
- /// Gets the dynamic property value.
- /// This method looks for the property by name in the dynamic object
- /// and retrieves the value of that property if found
- /// </summary>
- /// <param name="propertyName">Name of the property.</param>
- /// <param name="dynObject">The dyn object.</param>
- /// <returns></returns>
- public static dynamic GetObjectPropertyValue(string propertyName, dynamic dynObject)
- {
- PropertyInfo property = dynObject.GetType().GetProperty(propertyName);
-
- return property == null ? null : property.GetValue(dynObject, null);
- }
-
- /// <summary>
- /// Calls the method.
- /// </summary>
- /// <param name="objectType">Type of the object that contains the method.</param>
- /// <param name="methodName">Name of the method.</param>
- /// <param name="sourceRow">The source row to search for parameters in.</param>
- /// <returns></returns>
- public static dynamic CallMethod(Type objectType, string methodName, DataRow sourceRow)
- {
- var methodInfo = objectType.GetMethod(methodName);
- var parameters = new List<object>();
-
- methodInfo.GetParameters();
-
- foreach (var param in methodInfo.GetParameters())
- {
- var name = param.Name;
- object value = null;
-
- if (sourceRow.Table.Columns.Contains(name))
- value = GetValueFromColumn(sourceRow[name]);
- ;
- parameters.Add(value);
- }
-
- return methodInfo.Invoke(null, parameters.ToArray());
- }
-
- /// <summary>
- /// Calls the method.
- /// </summary>
- /// <param name="objectType">Type of the object that contains the method.</param>
- /// <param name="methodName">Name of the method.</param>
- /// <param name="sourceParams"></param>
- /// <returns></returns>
- public static dynamic CallMethod(Type objectType, string methodName, dynamic sourceParams)
- {
- var methodInfo = objectType.GetMethod(methodName);
- var parameters = new List<object>();
-
- methodInfo.GetParameters();
-
- foreach (var param in methodInfo.GetParameters())
- {
- var value = DynamicObjectMethods.GetObjectPropertyValue(param.Name, sourceParams);
-
- parameters.Add(value);
- }
-
- return methodInfo.Invoke(null, parameters.ToArray());
- }
-
- /// <summary>
- /// Sets the list object values for type T; List of T or Array of T[].
- /// </summary>
- /// <param name="trgtPropInfo">The Target property info.</param>
- /// <param name="sourceList">The source list or array of type T.</param>
- /// <returns></returns>
- public static dynamic SetListObjectValues(PropertyInfo trgtPropInfo, dynamic sourceList, int mType)
- {
- dynamic targetList; // empty list object of type T
- dynamic targetListObjectType; // type T of list object property
- dynamic target; // object of type T
-
- // get the property type of the list object type T; List<T> / T[]
- dynamic targetListPropertyType = trgtPropInfo.PropertyType;
-
- // targetList is an Array T[].
- if (targetListPropertyType.IsArray)
- {
- //get the target property type that is the array object type T
- targetListObjectType = targetListPropertyType.GetElementType();
-
- // instantiate an empty array list of the object type
- targetList = Array.CreateInstance(targetListObjectType, sourceList.Count);
-
- var i = 0;
- foreach (var source in sourceList)
- {
- // instantiate the object that is the list object type T
- target = Activator.CreateInstance(targetListObjectType);
-
- //if unable to instantiate the list object, skip
- if (target == null) continue;
-
- dynamic addObject = mType == 1 ? SetServiceTargetPropertyValues(target, source) : GetServiceSourcePropertyValues(target, source);
-
- //array[i] = item as typeof(type);
- targetList[i] = addObject;
- i++;
- }
- }
- else // targetList is a List<T>.
- {
- // instantiate an empty List<T> of the object type
- targetList = Activator.CreateInstance(trgtPropInfo.PropertyType);
-
- //get the target property type that is the List<T> object type T
- targetListObjectType = targetList.GetType().GetProperty("Item").PropertyType;
-
- foreach (var source in sourceList)
- {
- // instantiate the object that is the list object type T
- target = Activator.CreateInstance(targetListObjectType);
-
- //if unable to instantiate the list object, skip
- if (target == null) continue;
-
- dynamic addObject = mType == 1 ? SetServiceTargetPropertyValues(target, source) : GetServiceSourcePropertyValues(target, source);
-
- targetList.Add(addObject);
- }
- }
-
- return targetList;
- }
-
- /// <summary>
- /// Sets the target property values.
- /// This method loops through the source properties and gets
- /// the equivalent target property.
- /// If the property is found in the target object,
- /// that properties value is set in the target objects property.
- /// </summary>
- /// <param name="target">The Service (empty) target object.</param>
- /// <param name="source">The Local (data filled) source object.</param>
- /// <returns>
- /// The property value (data) filled target object
- /// </returns>
- public static dynamic SetServiceTargetPropertyValues(dynamic target, dynamic source)
- {
- //loop through all source object properties declared
- foreach (var srcProperty in source.GetType().GetProperties())
- {
- // get the source object property value
- var propertyValue = srcProperty.GetValue(source, null);
-
- // Check of the source property value is null.
- // This enables nullable (OPTIONAL) fields
- // to be ignored if no value is present at runtime
- if (propertyValue == null) continue;
-
- // Get the equivalent target object property
- var trgtProperty = target.GetType().GetProperty(srcProperty.Name);
-
- // Check of the target property is null (does not exist).
- // This is a guarantee if the target property sdoes not exist
- // we do not attempt to pass a value to it.
- if (trgtProperty == null) continue;
-
- // Check if the current target property and the source property are user defined objects with properties
- // if so, use recursion to fill all levels of objects in the target object
- if (IsUserDefinedObject(trgtProperty.PropertyType, srcProperty.PropertyType))
- {
- if (trgtProperty.PropertyType.IsArray)
- {
- //get the target property type that is the list object
- var tpType = trgtProperty.PropertyType.GetElementType();
-
- // did we get the target property type?
- if (tpType == null) continue;
-
- trgtProperty.SetValue(target, SetListObjectValues(trgtProperty, propertyValue, 1), null);
- }
- else if ((srcProperty.PropertyType.IsEnum) && (trgtProperty.PropertyType == typeof(string)))
- { //the source is an enum and the target is not
- // recursion is not necessary, get string value of enum
- trgtProperty.SetValue(target, propertyValue.ToString(), null);
- }
- else if ((srcProperty.PropertyType == typeof(string)) && (trgtProperty.PropertyType.IsEnum))
- { //the source is a string value and the target is an enum type
- // recursion is not necessary, set the value of enum with string value
- trgtProperty.SetValue(target, Enum.Parse(trgtProperty.PropertyType, propertyValue), null);
- }
- else
- {
- // instantiate the object that is the property type
- var nestObject = trgtProperty.PropertyType.InvokeMember(trgtProperty.Name, BindingFlags.CreateInstance, null, null, null);
-
- // did we get the nested class object?
- if (nestObject == null) continue;
-
- // recurse through the new objects
- trgtProperty.SetValue(target, SetServiceTargetPropertyValues(nestObject, propertyValue), null);
- }
-
- }
- else //set the System Property value in the Web Service Object
- trgtProperty.SetValue(target, propertyValue, null);
-
- }
-
- return target;
- }
-
- /// <summary>
- /// Gets the source property values.
- /// This method loops through the target object's properties and gets the
- /// equivalent source property.
- /// If the property is found in the source object,
- /// that properties value is set in the target objects property.
- /// </summary>
- /// <param name="target">The (empty) target object.</param>
- /// <param name="source">The data filled web service source object.</param>
- /// <returns>
- /// The property value (data) filled target object
- /// </returns>
- public static dynamic GetServiceCamelCaseSourcePropertyValues(dynamic target, dynamic source)
- {
- //loop through all properties declared in the dynamic target object
- foreach (var trgtProperty in target.GetType().GetProperties())
- {
- string propertyName = trgtProperty.Name;
- bool found = false;
- // find the equivalent source object property
- var srcProperty = source.GetType().GetProperty(MakeCamelCase(propertyName));
- if (srcProperty != null)
- found = true;
-
- if (!found)
- srcProperty = source.GetType().GetProperty(trgtProperty.Name);
-
- if (srcProperty != null)
- found = true;
-
- if (!found)
- srcProperty = source.GetType().GetProperty(propertyName.ToLower());
-
- // Check of the property is null (does not exist).
- if (srcProperty == null) continue;
-
- // get the source object property value
- var propertyValue = srcProperty.GetValue(source, null);
-
- // Check of the property value is null.
- if (propertyValue == null) continue;
-
- // Check if the current target property and the source property are user defined objects with properties
- // if so, use recursion to fill all levels of objects in the target object
- if (IsUserDefinedObject(srcProperty.PropertyType, trgtProperty.PropertyType))
- {
- if (srcProperty.PropertyType.IsArray)
- {
- trgtProperty.SetValue(target, SetListObjectValues(trgtProperty, propertyValue, 2), null);
- }
- else if ((srcProperty.PropertyType.IsEnum) && (trgtProperty.PropertyType == typeof(string)))
- { //the source is an enum and the target is not
- // recursion is not necessary, get string value of enum
- trgtProperty.SetValue(target, propertyValue.ToString(), null);
- }
- //else if ((srcProperty.PropertyType.IsEnum) && (trgtProperty.PropertyType.IsEnum))
- //{ //both properties are enums
- // // recurse through the enum objects
- // trgtProperty.SetValue(target, propertyValue, null);
- //}
- else
- {
- // instantiate the object that is the property type
- var nestObject = trgtProperty.PropertyType.InvokeMember(trgtProperty.Name, BindingFlags.CreateInstance, null, null, null);
-
- // did we get the nested class object?
- if (nestObject == null) continue;
-
- // recurse through the new objects
- trgtProperty.SetValue(target, GetServiceSourcePropertyValues(nestObject, propertyValue), null);
- }
-
- }
- else //set the System Property value in the Web Service Object
- trgtProperty.SetValue(target, propertyValue, null);
-
- }
-
- return target;
- }
-
- /// <summary>
- /// Gets the service source property values.
- /// This method loops through the target object's properties and gets the
- /// equivalent source property.
- /// If the property is found in the source object,
- /// that properties value is set in the target objects property.
- /// </summary>
- /// <param name="target">The (empty) target object.</param>
- /// <param name="source">The data filled web service source object.</param>
- /// The property value (data) filled target object
- /// <returns></returns>
- public static dynamic GetServiceSourcePropertyValues(dynamic target, dynamic source)
- {
- //loop through all properties declared in the dynamic target object
- foreach (var trgtProperty in target.GetType().GetProperties())
- {
- // find the equivalent source object property
- var srcProperty = source.GetType().GetProperty(trgtProperty.Name);
-
- // Check of the property is null (does not exist).
- // This makes a guarantee if property does not exist
- // we do not attempt to get a value from it.
- if (srcProperty == null) continue;
-
- // get the source object property value
- var propertyValue = srcProperty.GetValue(source, null);
-
- // Check of the property value is null.
- // This makes a guarantee if property value does not exist
- // we do not attempt to get a value from it.
- if (propertyValue == null) continue;
-
- // Check if the current target property and the source property are user defined objects with properties
- // if so, use recursion to fill all levels of objects in the target object
- if (IsUserDefinedObject(srcProperty.PropertyType, trgtProperty.PropertyType))
- {
- if (srcProperty.PropertyType.IsArray)
- {
- trgtProperty.SetValue(target, SetListObjectValues(trgtProperty, propertyValue, 2), null);
- }
- else if ((srcProperty.PropertyType.IsEnum) && (trgtProperty.PropertyType == typeof(string)))
- { //the source is an enum and the target is not
- // recursion is not necessary, get string value of enum
- trgtProperty.SetValue(target, propertyValue.ToString(), null);
- }
- //else if ((srcProperty.PropertyType.IsEnum) && (trgtProperty.PropertyType.IsEnum))
- //{ //both properties are enums
- // // recurse through the enum objects
- // trgtProperty.SetValue(target, propertyValue, null);
- //}
- else
- {
- // instantiate the object that is the property type
- var nestObject = trgtProperty.PropertyType.InvokeMember(trgtProperty.Name, BindingFlags.CreateInstance, null, null, null);
-
- // did we get the nested class object?
- if (nestObject == null) continue;
-
- // recurse through the new objects
- trgtProperty.SetValue(target, GetServiceSourcePropertyValues(nestObject, propertyValue), null);
- }
-
- }
- else //set the System Property value in the Web Service Object
- trgtProperty.SetValue(target, propertyValue, null);
-
- }
-
- return target;
- }
-
- /// <summary>
- /// Determines if the properties are class object types and need recursion.
- /// If this method is failing,
- /// ensure the FBMC user defined objects are created properly
- /// </summary>
- /// <param name="trgtPropType">Type of the target property.</param>
- /// <param name="srcPropType">Type of the source property.</param>
- /// <returns></returns>
- public static bool IsUserDefinedObject(Type trgtPropType, Type srcPropType)
- {
- // the namespace of the defined objects
- var trgNamespace = trgtPropType.Namespace;
- var srcNamespace = srcPropType.Namespace;
-
- // both Objects are System defined objects
- if ((trgNamespace == "System") && (srcNamespace == "System")) return false;
-
- // both Objects are "User" defined (i.e. not "System" defined objects)
- if ((!trgNamespace.Contains("System.")) && (!srcNamespace.Contains("System.")))
- return true;
-
- // see if either object is a "User" defined object
- if ((!trgNamespace.Contains("System.")) || (!srcNamespace.Contains("System.")))
- {
- /***** at least one object is user defined *****/
-
- // see if either object is an enumeration
- if ((trgtPropType.IsEnum) || (srcPropType.IsEnum))
- return true;
-
- // see if both objects are an array or a list
- if (((trgtPropType.IsArray) || (trgtPropType.IsSerializable))
- && ((srcPropType.IsArray) || (srcPropType.IsSerializable)))
- return true;
- }
-
- // both objects are system defined objects and not enums
- // no recursion is necessary
- return false;
- }
-
- /// <summary>
- /// Gets the value from column.
- /// </summary>
- /// <param name="value">The value.</param>
- /// <returns></returns>
- public static dynamic GetValueFromColumn(object value)
- {
- if (Convert.IsDBNull(value)) return null;
-
- var rtnValue = default(dynamic);
-
- if (value is string)
- rtnValue = Convert.ToString(value);
- else if (value is int)
- rtnValue = Convert.ToInt32(value);
- else if (value is DateTime)
- rtnValue = Convert.ToDateTime(value);
- else if (value is decimal)
- rtnValue = Convert.ToDecimal(value);
-
- return rtnValue;
- }
-
- private static string MakePascalCase(string inStr)
- {
- if (inStr.Length > 0)
- {
- if (inStr.ToUpper() == "ID") // Always return an ID as a capped field
- return inStr.ToUpper();
-
- //convert the first letter in the word to uppercase
- char firstLetter = char.ToUpper(inStr[0]);
-
- //concantenate the uppercase letter to the rest of the word
- inStr = firstLetter + inStr.Substring(1);
- }
- return inStr;
- }
-
- private static string MakeCamelCase(string inStr)
- {
- if (inStr.Length > 0)
- {
- //convert the first letter in the word to uppercase
- char firstLetter = char.ToLower(inStr[0]);
-
- //concantenate the uppercase letter to the rest of the word
- inStr = firstLetter + inStr.Substring(1);
- }
- return inStr;
- }
-
-
-
- }
- }