HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Redis Object storage and conversion

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
redisconversionstorageandobject

Problem

I am stepping into a new realm with this project, Reflection. I have written some working code (below) that will potentially store POCO objects in a redis cache (and eventually backed by Table or other nosql persistant storage).

Currently it only reads the objects from the cache, but after this review I will be attempting to reverse the process and store the POCOs in the cache.

I am posting this due to my weakness with Reflection, but feel free to correct me on any other issues.

```
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Demgel.Redis.Attributes;
using StackExchange.Redis;

namespace Demgel.Redis
{
public static class DemgelRedis
{
public static IEnumerable ConvertToRedisHash(object o, bool ignoreFail = false)
{
var hashList = new List();
foreach (var prop in o.GetType().GetProperties())
{
var type = prop.PropertyType;
if (type.IsAssignableFrom(typeof (Guid)))
{
var guid = prop.GetValue(o, null) as Guid?;
if (guid.HasValue)
{
hashList.Add(new HashEntry(prop.Name, guid.Value.ToString()));
}
}
else if (type.IsAssignableFrom(typeof(string)))
{
var value = prop.GetValue(o, null) as string;
if (value != null)
{
hashList.Add(new HashEntry(prop.Name, value));
}
}

}
return hashList;
}

public static object ConvertToObject(object obj, HashEntry[] hashEntries, bool ignoreFail = false)
{
var hashDict = hashEntries.ToDictionary();

foreach (var prop in obj.GetType().GetProperties())
{
RedisValue hashPair;
if (!hashDict.TryGetValu

Solution

If I focus on how ConvertToRedisHash is returning its IEnumerable, I get this:

public static IEnumerable ConvertToRedisHash(object o, bool ignoreFail = false)
{
    var hashList = new List();
    foreach (var prop in o.GetType().GetProperties())
    {
        ...
        hashList.Add(new HashEntry(prop.Name, guid.Value.ToString()));
        ...
        hashList.Add(new HashEntry(prop.Name, value));
        ...
    }
    return hashList;
}


You're returning an IEnumerable, but you're not returning anything until you've collected every item and added them to a List. You could instead drop that List, and yield return the results as they become available:

public static IEnumerable ConvertToRedisHash(object o, bool ignoreFail = false)
{
    foreach (var prop in o.GetType().GetProperties())
    {
        ...
        yield return new HashEntry(prop.Name, guid.Value.ToString());
        ...
        yield return new HashEntry(prop.Name, value);
        ...
    }
}


There's a typo with RetreiveObject, should be RetrieveObject ;-)

I don't like this part:

var type = prop.PropertyType;
if (type.IsAssignableFrom(typeof(Guid)))
{
    Guid value;
    if (!Guid.TryParse(hashPair, out value))
    {
        try
        {
            value = new Guid((byte[]) hashPair);
        }
        catch
        {
            value = Guid.Empty;
        }
    }
    prop.SetValue(obj, value);
}
else if (type.IsAssignableFrom(typeof(string)))
{
    prop.SetValue(obj, (string)hashPair);
}
else if (type.IsAssignableFrom(typeof(float)))
{
    prop.SetValue(obj, (float)Convert.ToDouble(hashPair));
}
else if (type.IsAssignableFrom(typeof(double)))
{
    prop.SetValue(obj, Convert.ToDouble(hashPair));
}
else if (type.IsAssignableFrom(typeof(int)))
{
    prop.SetValue(obj, int.Parse(hashPair));
}
else if (type.IsAssignableFrom(typeof (DateTime)))
{
    DateTime dateTime;
    if (DateTime.TryParse(hashPair, out dateTime))
    {
        prop.SetValue(obj, dateTime);
    }
}


It seems it would be better off as a switch block.

Code Snippets

public static IEnumerable<HashEntry> ConvertToRedisHash(object o, bool ignoreFail = false)
{
    var hashList = new List<HashEntry>();
    foreach (var prop in o.GetType().GetProperties())
    {
        ...
        hashList.Add(new HashEntry(prop.Name, guid.Value.ToString()));
        ...
        hashList.Add(new HashEntry(prop.Name, value));
        ...
    }
    return hashList;
}
public static IEnumerable<HashEntry> ConvertToRedisHash(object o, bool ignoreFail = false)
{
    foreach (var prop in o.GetType().GetProperties())
    {
        ...
        yield return new HashEntry(prop.Name, guid.Value.ToString());
        ...
        yield return new HashEntry(prop.Name, value);
        ...
    }
}
var type = prop.PropertyType;
if (type.IsAssignableFrom(typeof(Guid)))
{
    Guid value;
    if (!Guid.TryParse(hashPair, out value))
    {
        try
        {
            value = new Guid((byte[]) hashPair);
        }
        catch
        {
            value = Guid.Empty;
        }
    }
    prop.SetValue(obj, value);
}
else if (type.IsAssignableFrom(typeof(string)))
{
    prop.SetValue(obj, (string)hashPair);
}
else if (type.IsAssignableFrom(typeof(float)))
{
    prop.SetValue(obj, (float)Convert.ToDouble(hashPair));
}
else if (type.IsAssignableFrom(typeof(double)))
{
    prop.SetValue(obj, Convert.ToDouble(hashPair));
}
else if (type.IsAssignableFrom(typeof(int)))
{
    prop.SetValue(obj, int.Parse(hashPair));
}
else if (type.IsAssignableFrom(typeof (DateTime)))
{
    DateTime dateTime;
    if (DateTime.TryParse(hashPair, out dateTime))
    {
        prop.SetValue(obj, dateTime);
    }
}

Context

StackExchange Code Review Q#106891, answer score: 3

Revisions (0)

No revisions yet.