private Func <object, byte[]> GenerateSerializer(Type type) { var typeCode = Type.GetTypeCode(type); switch (typeCode) { case TypeCode.Boolean: return(value => ValueSerialization.Serialize(ColumnType.Boolean, value)); case TypeCode.Decimal: return(value => ValueSerialization.Serialize(ColumnType.Decimal, value)); case TypeCode.Double: return(value => ValueSerialization.Serialize(ColumnType.Double, value)); case TypeCode.Single: return(value => ValueSerialization.Serialize(ColumnType.Float, value)); case TypeCode.Char: return(value => ValueSerialization.Serialize(ColumnType.Int, (int)(char)value)); case TypeCode.Byte: return(value => ValueSerialization.Serialize(ColumnType.Int, (int)(byte)value)); case TypeCode.SByte: return(value => ValueSerialization.Serialize(ColumnType.Int, (int)(sbyte)value)); case TypeCode.UInt16: return(value => ValueSerialization.Serialize(ColumnType.Int, (int)(ushort)value)); case TypeCode.Int16: return(value => ValueSerialization.Serialize(ColumnType.Int, (int)(short)value)); case TypeCode.Int32: return(value => ValueSerialization.Serialize(ColumnType.Int, value)); case TypeCode.UInt32: return(value => ValueSerialization.Serialize(ColumnType.Bigint, (long)(uint)value)); case TypeCode.Int64: return(value => ValueSerialization.Serialize(ColumnType.Bigint, value)); case TypeCode.String: return(value => ValueSerialization.Serialize(ColumnType.Varchar, value)); case TypeCode.DateTime: return(value => ValueSerialization.Serialize(ColumnType.Timestamp, value)); case TypeCode.Empty: return(null); default: return(GenerateObjectSerializer(type)); } }
private Func <object, byte[]> GenerateObjectSerializer(Type type) { var customSerializer = type.GetCustomAttributes(typeof(CassandraTypeSerializerAttribute), false).FirstOrDefault() as CassandraTypeSerializerAttribute; if (customSerializer != null) { return(value => customSerializer.Serializer.Serialize(value)); } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { return(GenerateSerializer(type.GetGenericArguments()[0])); } if (typeof(Guid).IsAssignableFrom(type)) { return(value => ValueSerialization.Serialize(ColumnType.Uuid, value)); } if (typeof(IPAddress).IsAssignableFrom(type)) { return(value => ValueSerialization.Serialize(ColumnType.Inet, value)); } if (typeof(Enum).IsAssignableFrom(type)) { var enumType = type.GetEnumUnderlyingType(); return(GenerateSerializer(enumType)); } if (typeof(byte[]).IsAssignableFrom(type)) { return(value => ValueSerialization.Serialize(ColumnType.Blob, value)); } if (typeof(IDictionary).IsAssignableFrom(type)) { var dictionaryTypeDef = type.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDictionary <,>)); if (dictionaryTypeDef != null) { var dictionaryArgs = dictionaryTypeDef.GetGenericArguments(); var keySerializer = GenerateSerializer(dictionaryArgs[0]); var valueSerializer = GenerateSerializer(dictionaryArgs[1]); return(value => ValueSerialization.SerializeMap((IDictionary)value, keySerializer, valueSerializer)); } } if (typeof(IList).IsAssignableFrom(type)) { var listTypeDef = type.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IList <>)); if (listTypeDef != null) { var listItemType = listTypeDef.GetGenericArguments()[0]; var valueSerializer = GenerateSerializer(listItemType); return(value => ValueSerialization.SerializeList((IList)value, valueSerializer)); } } var hashSetTypeDef = type.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ISet <>)); if (hashSetTypeDef != null) { var setItemType = hashSetTypeDef.GetGenericArguments()[0]; var valueSerializer = GenerateSerializer(setItemType); return(value => { Type setAccessorType = typeof(HashSetAccessor <>).MakeGenericType(setItemType); var hashSet = (IHashSetAccessor)Activator.CreateInstance(setAccessorType, value); return ValueSerialization.SerializeSet(hashSet, valueSerializer); }); } throw new NotSupportedException(string.Format("Type {0} neither belongs to Cassandra native types nor has custom serializer defined. Use CassandraTypeSerializerAttribute to define custom type serializer to store data inside Blob column.", type.FullName)); }