/// <summary> /// Instantiates a new instance of objectType. /// </summary> /// <param name="objectType"></param> /// <returns>objectType instance</returns> internal object InstantiateObjectDefaultCtor(Type targetType) { if (targetType == null || targetType.IsValueType || targetType.IsAbstract || targetType == typeof(object) || targetType == typeof(string)) { return(new JsonObject()); } targetType = TypeCoercionUtility.ResolveInterfaceType(targetType); if (targetType.IsInterface) { return(new JsonObject()); } FactoryMap factory = this.ResolverCache.LoadFactory(targetType); if ((factory == null) || (factory.Ctor == null) || ((factory.CtorArgs != null) && (factory.CtorArgs.Length > 0))) { return(new JsonObject()); } // default constructor return(factory.Ctor()); }
private object CoerceList(Type targetType, Type valueType, IEnumerable value) { targetType = TypeCoercionUtility.ResolveInterfaceType(targetType); if (targetType.IsArray) { // arrays are much simpler to create return(this.CoerceArray(targetType.GetElementType(), value)); } // targetType serializes as a JSON array but is not an array // assume is an ICollection or IEnumerable with AddRange, Add, // or custom Constructor with which we can populate it FactoryMap factory = this.ResolverCache.LoadFactory(targetType); if (factory == null) { throw new TypeCoercionException(String.Format( TypeCoercionUtility.ErrorCtor, targetType.FullName)); } foreach (Type argType in factory.ArgTypes) { if (argType.IsAssignableFrom(valueType)) { try { // invoke first constructor that can take this value as an argument return(factory[argType](value)); } catch { // there might exist a better match continue; } } } if (factory.Ctor == null) { throw new TypeCoercionException(String.Format( TypeCoercionUtility.ErrorCtor, targetType.FullName)); } // attempt bulk insert first as is most efficient if (factory.AddRange != null && factory.AddRangeType != null && factory.AddRangeType.IsAssignableFrom(valueType)) { object collection = factory.Ctor(); factory.AddRange(collection, value); return(collection); } // attempt sequence of single inserts next if (factory.Add != null && factory.AddType != null) { object collection = factory.Ctor(); Type addType = factory.AddType; // loop through adding items to collection foreach (object item in value) { factory.Add(collection, this.CoerceType(addType, item)); } return(collection); } try { // finally fall back to basics return(Convert.ChangeType(value, targetType, CultureInfo.InvariantCulture)); } catch (Exception ex) { throw new TypeCoercionException( String.Format( "Error converting {0} to {1}", value.GetType().FullName, targetType.FullName), ex); } }
/// <summary> /// Instantiates a new instance of objectType. /// </summary> /// <param name="objectType"></param> /// <returns>objectType instance</returns> internal object InstantiateObject(Type targetType, object args) { targetType = TypeCoercionUtility.ResolveInterfaceType(targetType); FactoryMap factory = this.ResolverCache.LoadFactory(targetType); if ((factory == null) || (factory.Ctor == null)) { throw new TypeCoercionException(String.Format( TypeCoercionUtility.ErrorCtor, targetType.FullName)); } if ((factory.CtorArgs == null) || (factory.CtorArgs.Length < 1)) { // default constructor return(factory.Ctor()); } object[] ctorArgs = new object[factory.CtorArgs.Length]; IDictionary <string, object> genericArgs = args as IDictionary <string, object>; if (genericArgs != null) { for (int i = 0, length = ctorArgs.Length; i < length; i++) { string name = factory.CtorArgs[i].Name; Type type = factory.CtorArgs[i].ParameterType; foreach (string key in genericArgs.Keys) { try { if (StringComparer.OrdinalIgnoreCase.Equals(key, name)) { ctorArgs[i] = this.CoerceType(type, genericArgs[key]); break; } } catch { } } } } else { IDictionary otherArgs = args as IDictionary; if (otherArgs != null) { for (int i = 0, length = ctorArgs.Length; i < length; i++) { string name = factory.CtorArgs[i].Name; Type type = factory.CtorArgs[i].ParameterType; foreach (string key in otherArgs.Keys) { try { if (StringComparer.OrdinalIgnoreCase.Equals(key, name)) { ctorArgs[i] = this.CoerceType(type, otherArgs[key]); break; } } catch { } } } } } // use a custom constructor return(factory.Ctor(ctorArgs)); }