Created
December 17, 2015 09:33
-
-
Save gongdo/3f67715faaac346631ce to your computer and use it in GitHub Desktop.
StringEnumTableEntity that extends TableEntity in order to support enum properties when Read/WriteEntity.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Represents the base object type for a table entity in the Table service. | |
/// </summary> | |
/// <remarks> | |
/// ReadEntity deserializes enum properties from string values which have same name. | |
/// Property name comparison is case-insensitive. | |
/// Also WriteEntity serializes enum properties as string values. | |
/// </remarks> | |
public abstract class StringEnumTableEntity : TableEntity | |
{ | |
private readonly IReadOnlyDictionary<string, PropertyInfo> | |
EnumProperties; | |
public StringEnumTableEntity() | |
{ | |
EnumProperties = GetEnumProperties(GetType()); | |
} | |
public StringEnumTableEntity(string partitionKey, string rowKey) | |
: base(partitionKey, rowKey) | |
{ | |
EnumProperties = GetEnumProperties(GetType()); | |
} | |
private static Dictionary<string, PropertyInfo> | |
GetEnumProperties(Type type) | |
{ | |
return type.GetTypeInfo() | |
.DeclaredProperties | |
.Where(p => p.PropertyType.GetTypeInfo().IsEnum) | |
.ToDictionary(p => p.Name, p => p); | |
} | |
public override void ReadEntity( | |
IDictionary<string, EntityProperty> properties, | |
OperationContext operationContext) | |
{ | |
base.ReadEntity(properties, operationContext); | |
properties | |
.Where(p => EnumProperties.ContainsKey(p.Key)) | |
.Select(p => new | |
{ | |
p.Value.StringValue, | |
Property = EnumProperties[p.Key] | |
}) | |
.ToList() | |
.ForEach(item => | |
{ | |
var enumValue = Enum.Parse( | |
item.Property.PropertyType, | |
item.StringValue); | |
item.Property.SetValue(this, enumValue); | |
}); | |
} | |
public override IDictionary<string, EntityProperty> WriteEntity( | |
OperationContext operationContext) | |
{ | |
var dictionary = base.WriteEntity(operationContext); | |
EnumProperties | |
.Select(p => new | |
{ | |
p.Key, | |
Value = p.Value.GetValue(this).ToString(), | |
}) | |
.ToList() | |
.ForEach(item => | |
{ | |
dictionary.Add(item.Key, new EntityProperty(item.Value)); | |
}); | |
return dictionary; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class StringEnumTableEntityTest | |
{ | |
[Fact] | |
public void WriteEntity_adds_enum_properties() | |
{ | |
var entity = new DummyEntity(); | |
var values = entity.WriteEntity(null); | |
Assert.Equal(DummyEnum.Cat.ToString(), values["Enum1"].StringValue); | |
Assert.Equal(DummyEnum.Dog.ToString(), values["Enum2"].StringValue); | |
} | |
[Fact] | |
public void ReadEntity_sets_enum_properties() | |
{ | |
var entity = new DummyEntity(); | |
entity.ReadEntity(new Dictionary<string, EntityProperty> | |
{ | |
{ "Enum1", EntityProperty.GeneratePropertyForString(DummyEnum.Dog.ToString()) }, | |
{ "Enum2", EntityProperty.GeneratePropertyForString(DummyEnum.Cat.ToString()) }, | |
}, null); | |
Assert.Equal(DummyEnum.Dog, entity.Enum1); | |
Assert.Equal(DummyEnum.Cat, entity.Enum2); | |
} | |
[Fact] | |
public void ReadEntity_ignores_case() | |
{ | |
var entity = new DummyEntity(); | |
entity.ReadEntity(new Dictionary<string, EntityProperty> | |
{ | |
{ "eNum1", EntityProperty.GeneratePropertyForString(DummyEnum.Dog.ToString()) }, | |
{ "enUm2", EntityProperty.GeneratePropertyForString(DummyEnum.Cat.ToString()) }, | |
}, null); | |
Assert.Equal(DummyEnum.Dog, entity.Enum1); | |
Assert.Equal(DummyEnum.Cat, entity.Enum2); | |
} | |
public enum DummyEnum | |
{ | |
Cat, | |
Dog, | |
Monkey | |
} | |
public class DummyEntity : StringEnumTableEntity | |
{ | |
public DummyEnum Enum1 { get; set; } = DummyEnum.Cat; | |
public DummyEnum Enum2 { get; set; } = DummyEnum.Dog; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment