Пример #1
0
        public override async Task WriteAsync(RedisConvert convert, Type objectType, object value, Namespace name, TimeSpan?TTL = null)
        {
            //Prepare the options
            RedisOptionAttribute options = objectType.GetCustomAttribute <RedisOptionAttribute>();

            if (options == null)
            {
                options = new RedisOptionAttribute();
            }

            //Store it as a simple string
            if (options.SingleValueKey)
            {
                await convert.Client.StoreStringAsync(name.Build(), value.ToString(), TTL);

                return;
            }

            //The content that will be written to the HashMap in bulk
            Dictionary <string, string> hashmap = new Dictionary <string, string>();

            //Iterate over every property
            foreach (var property in objectType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                var ignoreAttribute = property.GetCustomAttribute <RedisIgnoreAttribute>();
                if (ignoreAttribute != null)
                {
                    continue;
                }

                //Prepare some property values
                var propertyName      = property.Name;
                var propertyAttribute = property.GetCustomAttribute <RedisPropertyAttribute>();
                if (propertyAttribute != null)
                {
                    propertyName = propertyAttribute.DisplayName ?? property.Name;
                }

                //Prepare the serializer
                var serializer = convert.GetSerializerForType(property.PropertyType, property: propertyAttribute);
                Debug.Assert(serializer != null);

                //Push the name and then serialize it
                name.Push(propertyName);
                convert.SetHashMapBuffer(hashmap);
                await serializer.WriteAsync(convert, property.PropertyType, property.GetValue(value), name, TTL);

                name.Pop();
            }

            //Flush our buffer
            convert.SetHashMapBuffer(hashmap);
            await convert.FlushHashMapAsync(name, TTL);
        }
Пример #2
0
        /// <summary>
        /// Serializes a object into a single dictionary
        /// </summary>
        /// <param name="buffer">The dictionary that all the keys will be inserted into</param>
        /// <param name="obj">The object to parse</param>
        /// <param name="subkey">The current subkey</param>
        public static void Serialize(Dictionary <string, string> buffer, object obj, string subkey = "")
        {
            //Prepare the type and initial options
            Type type = obj.GetType();

            //See if we should override the options
            RedisOptionAttribute options = type.GetCustomAttribute <RedisOptionAttribute>();

            //Iterate over every property
            foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                SerializeMember(buffer, new SerializeMember(property), obj, subkey);
            }

            //Iterate over every field
            foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                SerializeMember(buffer, new SerializeMember(field), obj, subkey);
            }
        }
Пример #3
0
        /// <summary>
        /// Gets the serializer for the given type.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="options"></param>
        /// <param name="property"></param>
        /// <returns></returns>
        public RedisSerializer GetSerializerForType(Type type, RedisOptionAttribute options = null, RedisPropertyAttribute property = null)
        {
            if (options != null && options.Serializer != null)
            {
                return((RedisSerializer)Activator.CreateInstance(options.Serializer));
            }

            if (property != null && property.Serializer != null)
            {
                return((RedisSerializer)Activator.CreateInstance(property.Serializer));
            }

            if (type.IsPrimitive || type.IsEnum || type == typeof(string))
            {
                return(new PrimitiveSerializer());
            }

            if (type.IsGenericType)
            {
                if (type.GetGenericTypeDefinition() == typeof(Dictionary <,>))
                {
                    return(new DictionarySerializer());
                }

                if (type.GetGenericTypeDefinition() == typeof(HashSet <>))
                {
                    return(new HashSetSerializer());
                }

                if (type.GetGenericTypeDefinition() == typeof(List <>))
                {
                    return(new ListSerializer());
                }
            }

            return(new ClassSerializer());
        }
Пример #4
0
        /// <summary>
        /// Deserializes a dictionary into a object
        /// </summary>
        /// <param name="buffer">The data that was received by the redis</param>
        /// <param name="type">The type of target object</param>
        /// <param name="reference">The target object</param>
        /// <param name="subkey">The subkey (optional)</param>
        /// <returns></returns>
        private static bool Deserialize(Dictionary <string, string> buffer, Type type, ref object reference, string subkey = "")
        {
            Debug.Assert(type != null);
            Debug.Assert(reference != null);
            Debug.Assert(buffer != null);

            //Prepare the type and initial options
            bool hasElements = false;

            //See if we should override the options
            RedisOptionAttribute options = type.GetCustomAttribute <RedisOptionAttribute>();

            if (options == null)
            {
                options = new RedisOptionAttribute();
            }

            //Create a new instance of the type
            foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (DeserializeMember(buffer, type, new SerializeMember(property), ref reference, subkey, options))
                {
                    hasElements = true;
                }
            }

            foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (DeserializeMember(buffer, type, new SerializeMember(field), ref reference, subkey, options))
                {
                    hasElements = true;
                }
            }

            //Return the element state
            return(hasElements);
        }
Пример #5
0
        private static bool DeserializeMember(Dictionary <string, string> buffer, Type type, SerializeMember member, ref object reference, string subkey, RedisOptionAttribute options)
        {
            //Ignore elements with ignore attributes
            var ignoreAttribute = member.GetCustomAttribute <RedisIgnoreAttribute>();

            if (ignoreAttribute != null)
            {
                return(false);
            }

            //Ignore generated blocks
            var generatedAttribute = member.GetCustomAttribute <System.Runtime.CompilerServices.CompilerGeneratedAttribute>();

            if (generatedAttribute != null)
            {
                return(false);
            }

            //Serialize the member if it has an attribute or is forced to serialize.
            var attribute = member.GetCustomAttribute <RedisPropertyAttribute>();

            if (attribute == null)
            {
                if (member.IsField)
                {
                    return(false);
                }
                attribute = new RedisPropertyAttribute(member.Name);
            }

            //Prepare its key
            string key = PrepareKey(attribute, member.Name, subkey);

            //If class, we have to do something completely different
            //If it has a serialize attribute, we want to construct its serializer
            //var serializerAttribute = member.GetCustomAttribute<RedisSerializerAttribute>();
            //if (serializerAttribute != null)
            //{
            //	//They have a custom serializer, so lets construct its type
            //	var constructor = serializerAttribute.Serializer.GetConstructor(new Type[0]);
            //	if (constructor != null)
            //	{
            //		var serializer = constructor.Invoke(new object[0]) as RedisSerializer;
            //		if (serializer != null)
            //		{
            //			object v = serializer.Deserialize(buffer, member, key);
            //			member.SetValue(reference, v);
            //			return true;
            //		}
            //
            //		throw new Exception("Bad Serialization on the custom serializer! Failed to cast into a RedisSerializer");
            //	}
            //
            //	throw new Exception("Bad Serialization on the custom serializer! Failed to find a constructor with 0 elements");
            //}

            //If the property is a string, just cast ez pz
            if (member.IsPrimitive || member.IsString || member.IsEnum)
            {
                string primval;
                if (buffer.TryGetValue(key, out primval))
                {
                    if (member.IsPrimitive || member.IsEnum)
                    {
                        object v = TypeDescriptor.GetConverter(member.Type).ConvertFromString(primval);
                        member.SetValue(reference, v);
                    }
                    else
                    {
                        member.SetValue(reference, primval);
                    }

                    return(true);
                }

                return(false);
            }

            //We have to do it the classical way with a subkey
            //var propvalConstructor = propertyType.GetConstructor(new Type[0]);
            //object propval = propvalConstructor.Invoke(new object[0]);
            object propval = null;

            try
            {
                propval = Activator.CreateInstance(member.Type);
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception while creating a instance!");
                throw e;
            }

            //Serialize
            if (propval != null && Deserialize(buffer, member.Type, ref propval, key + "."))
            {
                member.SetValue(reference, propval);
                return(true);
            }

            return(false);
        }