/// <summary> /// Constructs a new instance of the object represented by the expression. /// </summary> /// <param name="expression">json object expression</param> /// <param name="deserializer">deserializer for deserializing constructor arguments if any</param> /// <returns>constructed, but unpopulated object</returns> protected virtual object ConstructObject(ObjectExpression expression, IDeserializerHandler deserializer) { ITypeData handler = Settings.Types[expression.ResultType]; // set the default type if none set if (expression.ConstructorArguments.Count > 0) { // old way expects parameters in the constructor list ResolveConstructorTypes(Settings, expression); } else { foreach (IPropertyData parameter in handler.ConstructorParameters) { int propLocation = expression.IndexOf(parameter.Alias); if (propLocation >= 0) { Expression arg = expression.Properties[propLocation].ValueExpression; arg.ResultType = parameter.PropertyType; expression.ConstructorArguments.Add(arg); expression.Properties.RemoveAt(propLocation); } else { expression.ConstructorArguments.Add(new NullExpression()); } } } object[] args = new object[expression.ConstructorArguments.Count]; for (int i = 0; i < args.Length; i++) { Expression carg = expression.ConstructorArguments[i]; if (i < handler.ConstructorParameters.Count && handler.ConstructorParameters[i].HasConverter) { TypeConverterExpressionHandler converterHandler = (TypeConverterExpressionHandler)Settings.ExpressionHandlers.Find(typeof(TypeConverterExpressionHandler)); args[i] = converterHandler.Evaluate(carg, deserializer, handler.ConstructorParameters[i].TypeConverter); } else { args[i] = deserializer.Evaluate(carg); } } object result = handler.CreateInstance(args); expression.OnObjectConstructed(result); return(result); }
protected virtual void EvaluateItem(object existingObject, IDeserializerHandler deserializer, ITypeData typeHandler, KeyValueExpression Item) { // evaluate the item and let it assign itself? IPropertyData hndlr = typeHandler.FindPropertyByAlias(Item.Key); if (hndlr == null) { switch (this.Settings.MissingPropertyAction) { case MissingPropertyOptions.Ignore: return; case MissingPropertyOptions.ThrowException: throw new Exception(string.Format("Could not find property {0} for type {1}", Item.Key, typeHandler.ForType)); default: throw new InvalidOperationException("Unhandled MissingPropertyAction: " + this.Settings.MissingPropertyAction); } } if (hndlr.Ignored) { switch (Settings.IgnoredPropertyAction) { case IgnoredPropertyOption.Ignore: return; case IgnoredPropertyOption.SetIfPossible: if (!hndlr.CanWrite) { return; } break; case IgnoredPropertyOption.ThrowException: throw new Exception(string.Format("Can not set property {0} for type {1} because it is ignored and IgnorePropertyAction is set to ThrowException", Item.Key, typeHandler.ForType)); } } Expression valueExpression = Item.ValueExpression; valueExpression.ResultType = hndlr.PropertyType; object result = null; TypeConverterExpressionHandler converterHandler = null; IJsonTypeConverter converter = null; if (hndlr.HasConverter) { converterHandler = (TypeConverterExpressionHandler)Settings.ExpressionHandlers.Find(typeof(TypeConverterExpressionHandler)); converter = hndlr.TypeConverter; } if (!hndlr.CanWrite) { result = hndlr.GetValue(existingObject); if (converterHandler != null) { converterHandler.Evaluate(valueExpression, result, deserializer, converter); } else { deserializer.Evaluate(valueExpression, result); } } else { if (hndlr.HasConverter) { hndlr.SetValue(existingObject, converterHandler.Evaluate(valueExpression, deserializer, converter)); } else { hndlr.SetValue(existingObject, deserializer.Evaluate(valueExpression)); } } }