/// <summary> /// Initializes a new instance of the <see cref="AnonType"/> class with the /// anonymous instance to serialize. /// </summary> /// <param name="value">The anonymous value.</param> public AnonType(object value) { Ensure.NotNull(() => value); AnonymousTypeName = value.GetType().ToString(); PropertyNames = value.GetType().GetProperties() .Select(p => p.Name).ToArray(); List <AnonValue> values = new List <AnonValue>(); foreach (var name in PropertyNames) { var prop = value.GetType().GetProperty(name); var type = prop.PropertyType; var val = prop.GetValue(value); if (type.IsAnonymousType()) { val = new AnonType(val); type = typeof(AnonType); } values.Add(new AnonValue(type, val)); } PropertyValues = values.ToArray(); }
/// <summary> /// Initializes a new instance of the <see cref="AnonType"/> class /// with an anonymous type. /// </summary> /// <param name="anonymous">The anonymous type.</param> /// <param name="getKey">Function to get key for type.</param> public AnonType( object anonymous, Func <Type, string> getKey) { Ensure.NotNull(() => anonymous); AnonymousTypeKey = getKey(anonymous.GetType()); foreach (var prop in anonymous.GetType().GetProperties()) { var type = prop.PropertyType; var value = prop.GetValue(anonymous); var name = prop.Name; if (prop.PropertyType.IsAnonymousType()) { type = typeof(AnonType); value = new AnonType( value, getKey); } var anonTypeKey = getKey(type); Types.Add(anonTypeKey); Names.Add(name); Values.Add(value); } }
/// <summary> /// Initializes a new instance of the <see cref="AnonInitializer"/> class. /// </summary> /// <param name="typeName">The anonymous type name.</param> /// <param name="propertyNames">The proprty names.</param> /// <param name="values">The values.</param> public AnonInitializer(string typeName, string[] propertyNames, AnonValue[] values) { AnonValue = new AnonType { AnonymousTypeName = typeName, PropertyNames = propertyNames, PropertyValues = values, }; }
/// <summary> /// Initializes a new instance of the <see cref="AnonValue"/> class initalized /// with a type and value. /// </summary> /// <param name="type">The <see cref="Type"/> of the value.</param> /// <param name="value">The value.</param> public AnonValue(Type type, object value) { if (type.IsAnonymousType()) { type = typeof(AnonType); value = new AnonType(value); } AnonValueType = ServiceHost.GetService <IMemberAdapter>().GetKeyForMember(type); AnonVal = value; }
/// <summary> /// Unrolls anonymous types. /// </summary> /// <param name="valueType">The anonymous value type.</param> /// <param name="options">The serializer options.</param> /// <returns>The anonymous type.</returns> private object UnrollAnonymous(AnonType valueType, JsonSerializerOptions options) { var types = valueType.Types.Select(t => memberAdapter.Value.GetMemberForKey <Type>(t)).ToArray(); var values = new List <object>(); var newTypes = new List <Type>(); for (var idx = 0; idx < types.Length; idx++) { var obj = valueType.Values[idx]; if (obj is JsonElement json) { obj = JsonSerializer.Deserialize( json.GetRawText(), types[idx], options); } if (types[idx] == typeof(AnonType)) { obj = UnrollAnonymous(obj as AnonType, options); newTypes.Add(obj.GetType()); } else { newTypes.Add(types[idx]); } values.Add(obj); } var tuples = new List <(string prop, Type propType)>(); for (var idx = 0; idx < valueType.Names.Count; idx++) { tuples.Add((valueType.Names[idx], newTypes[idx])); } var type = memberAdapter.Value.MakeAnonymousType(tuples.ToArray()); var ctor = type.GetConstructors().First(); return(ctor.Invoke(values.ToArray())); }
/// <summary> /// Convert from <see cref="AnonType"/> back to anonymous type instance. /// </summary> /// <param name="anonType">The <see cref="AnonType"/>.</param> /// <param name="options">Serializer options.</param> /// <returns>The anonymous object.</returns> protected object ConvertAnonTypeToAnonymousType( AnonType anonType, JsonSerializerOptions options) => anonTypeAdapter.Value.ConvertFromAnonType( anonType, options);
/// <summary> /// Convert from <see cref="AnonType"/> back to anonymous type instance. /// </summary> /// <param name="anonType">The <see cref="AnonType"/>.</param> /// <returns>The anonymous object.</returns> protected object ConvertAnonTypeToAnonymousType( AnonType anonType) => anonTypeAdapter.Value.ConvertFromAnonType(anonType);
/// <summary> /// Reconstructs an anonymous type from <see cref="AnonType"/>. /// </summary> /// <param name="anonType">The <see cref="AnonType"/>.</param> /// <returns>The anonymous type instance.</returns> public object ConvertFromAnonType( AnonType anonType) { return(UnrollAnonymous(anonType)); }
/// <summary> /// Reconstructs an anonymous type from <see cref="AnonType"/>. /// </summary> /// <param name="anonType">The <see cref="AnonType"/>.</param> /// <param name="options">Serialization options.</param> /// <returns>The anonymous type instance.</returns> public object ConvertFromAnonType( AnonType anonType, JsonSerializerOptions options) { return(UnrollAnonymous(anonType, options)); }