using StackExchange.Redis; using System; using System.Text; namespace WX.CRM.DAL.Redis { public interface IRedisValueConverter { RedisValue Serialize(object value); object Deserialize(Type type, RedisValue value); } public static class RedisValueConverterExtensions { public static T Deserialize(this IRedisValueConverter converter, RedisValue value) { return (T)converter.Deserialize(typeof(T), value); } } /// /// Bass class of IRedisValueConverter for object serialization. /// If target is primitive type(int, double, string, etc), doesn't pass to core serializer. /// public abstract class ObjectRedisValueConverterBase : IRedisValueConverter { protected abstract object DeserializeCore(Type type, byte[] value); protected abstract byte[] SerializeCore(object value); static TypeCode GetNonNullableTypeCode(Type type) { return Type.GetTypeCode(Nullable.GetUnderlyingType(type) ?? type); } public object Deserialize(Type type, RedisValue value) { if (value.IsNull) { return null; } if (!value.HasValue) return null; var code = GetNonNullableTypeCode(type); switch (code) { case TypeCode.Empty: case TypeCode.DBNull: return RedisValue.Null; case TypeCode.SByte: return (SByte)value; case TypeCode.Byte: return (Byte)value; case TypeCode.Int16: return (Int16)value; case TypeCode.Int32: return (Int32)value; case TypeCode.Int64: return (Int64)value; case TypeCode.UInt16: return (UInt16)value; case TypeCode.UInt32: return (UInt32)value; case TypeCode.UInt64: return (UInt64)value; case TypeCode.Single: return (Single)value; case TypeCode.Double: return (Double)value; case TypeCode.Boolean: return (Boolean)value; case TypeCode.Char: return (Char)value; case TypeCode.String: byte[] strByte = value; return Encoding.UTF8.GetString(strByte); case TypeCode.DateTime: byte[] buf1 = value; return value.HasValue ? (value.ToString().Contains("/") ? Convert.ToDateTime(value) : DeserializeCore(type, buf1)) : DBNull.Value; default: byte[] buf = value; return DeserializeCore(type, buf); } } public RedisValue Serialize(object value) { var code = (value == null) ? TypeCode.Empty : Type.GetTypeCode(value.GetType()); switch (code) { case TypeCode.Empty: case TypeCode.DBNull: return string.Empty; case TypeCode.SByte: return (sbyte)value; case TypeCode.Byte: return (byte)value; case TypeCode.Int16: return (Int16)value; case TypeCode.Int32: return (Int32)value; case TypeCode.Int64: return (Int64)value; case TypeCode.UInt16: return (UInt16)value; case TypeCode.UInt32: return (UInt32)value; case TypeCode.UInt64: return (UInt64)value; case TypeCode.Single: return (Single)value; case TypeCode.Double: return (Double)value; case TypeCode.Boolean: return (Boolean)value; case TypeCode.Char: return (Char)value; case TypeCode.String: var strByte = Encoding.UTF8.GetBytes((string)value); return strByte; default: return SerializeCore(value); } } } }