/// <summary> /// Attempt to create object node from a .NET object. /// </summary> /// <param name="instance">Input object.</param> /// <returns> /// The new <see cref="JsonObjectNode"/> instance; otherwise a value of <c>null</c> /// if input was <c>null</c>. /// </returns> /// <exception cref="System.Exception"> /// If error is encountered whilst creating object node. Errors are likely to /// occur when unable to convert property values into JSON nodes. /// </exception> internal static JsonObjectNode FromInstance(object instance) { if (instance == null) { return(null); } var node = new JsonObjectNode(); var metaType = MetaType.FromType(instance.GetType()); metaType.InvokeOnSerializing(instance, default(StreamingContext)); foreach (var member in metaType.SerializableMembers) { object value; if (member.Info.MemberType == MemberTypes.Field) { var mi = (FieldInfo)member.Info; value = mi.GetValue(instance); } else { var pi = (PropertyInfo)member.Info; value = pi.GetValue(instance, null); } node[member.ResolvedName] = ConvertFrom(value); } metaType.InvokeOnSerialized(instance, default(StreamingContext)); return(node); }
/// <inheritdoc/> public override object ConvertTo(Type type) { if (type == null) { throw new ArgumentNullException("type"); } var obj = Activator.CreateInstance(type); var dictionary = obj as IDictionary; if (dictionary != null) { // Read properties into dictionary. var valueType = type.GetGenericArguments()[1]; foreach (var property in this.properties) { if (property.Value != null) { dictionary[property.Key] = property.Value.ConvertTo(valueType); } else { dictionary[property.Key] = null; } } } else { var metaType = MetaType.FromType(type); metaType.InvokeOnDeserializing(obj, default(StreamingContext)); // Read properties into object instance. foreach (var member in metaType.SerializableMembers) { var valueNode = this[member.ResolvedName]; if (valueNode == null) { continue; } if (member.Info.MemberType == MemberTypes.Field) { var fi = (FieldInfo)member.Info; fi.SetValue(obj, valueNode.ConvertTo(fi.FieldType)); } else { var pi = (PropertyInfo)member.Info; pi.SetValue(obj, valueNode.ConvertTo(pi.PropertyType), null); } } metaType.InvokeOnDeserialized(obj, default(StreamingContext)); } return(obj); }
public void FromType_CheckCache() { // Arrange var type = typeof(string); // Act var metaType1 = MetaType.FromType(type); var metaType2 = MetaType.FromType(type); // Assert Assert.IsNotNull(metaType1); Assert.AreSame(metaType1, metaType2); }
/// <summary> /// Attempt to create JSON node representation from given input. /// </summary> /// <remarks> /// <para>This method uses type information from input to determine which type of /// nodes seem best suited. Common basic data types are supported along with /// objects, structures, lists, native arrays and even dictionaries. Dictionary /// support is limited to those with string type keys (<c>Dictionary<string, YourType>></c>).</para> /// <para>Input value is simply cloned if it is already a <see cref="JsonNode"/>.</para> /// </remarks> /// <example> /// <para>Create JSON object from a generic dictionary:</para> /// <code language="csharp"><![CDATA[ /// // Prepare an example data structure. /// var lookupTable = new Dictionary<string, int>(); /// lookupTable["Player"] = 42; /// lookupTable["Boss1"] = 72; /// lookupTable["Whale"] = 128; /// /// // Convert example data structure into a JSON object. /// var jsonObject = JsonNode.FromObject(lookupTable); /// /// // Read node from JSON object. /// var playerNode = jsonObject["Player"] as JsonLongNode; /// Debug.Log(playerNode.Value); // 42 /// ]]></code> /// <para>Once you have a node representation of your data you can then proceed /// to output this to a JSON encoded text file:</para> /// <code language="csharp"><![CDATA[ /// File.WriteAllText(outputPath, jsonObject.ToString()); /// ]]></code> /// <para>The resulting text file would then look something like this:</para> /// <code language="json"><![CDATA[ /// { /// "Player": 42, /// "Boss1": 72, /// "Whale": 128 /// } /// ]]></code> /// </example> /// <param name="value">Input value, array, collection, object instance, etc.</param> /// <returns> /// The new <see cref="JsonNode"/> instance; or a value of <c>null</c> if input /// was itself a value of <c>null</c>. /// </returns> /// <exception cref="System.Exception"> /// If a problem was encountered whilst attempting to create node representation /// from input value. /// </exception> /// <seealso cref="ConvertTo{T}()"/> /// <seealso cref="ConvertTo(Type)"/> public static JsonNode ConvertFrom(object value) { if (value == null) { return(null); } var valueNode = value as JsonNode; if (valueNode != null) { return(valueNode.Clone()); } var type = value.GetType(); var metaType = MetaType.FromType(type); switch (metaType.TargetNodeType) { case MetaType.NodeType.Integer: if (Type.GetTypeCode(type) == TypeCode.UInt64) { return(new JsonIntegerNode((long)Convert.ToUInt64(value, CultureInfo.InvariantCulture))); } else { return(new JsonIntegerNode(Convert.ToInt64(value, CultureInfo.InvariantCulture))); } case MetaType.NodeType.Double: return(new JsonDoubleNode(Convert.ToDouble(value, CultureInfo.InvariantCulture))); case MetaType.NodeType.Boolean: return(new JsonBooleanNode(Convert.ToBoolean(value, CultureInfo.InvariantCulture))); case MetaType.NodeType.String: return(new JsonStringNode(Convert.ToString(value, CultureInfo.InvariantCulture))); case MetaType.NodeType.Array: if (type.IsArray) { return(JsonArrayNode.FromArray((object[])value)); } else { return(JsonArrayNode.FromCollection((IEnumerable)value)); } case MetaType.NodeType.Object: if (metaType.IsDictionaryStyleCollection) { return(FromDictionaryStyleCollection((ICollection)value, metaType)); } else { return(JsonObjectNode.FromInstance(value)); } default: throw new InvalidOperationException("Was unable to convert input value."); } }