Skip to content

Instantly share code, notes, and snippets.

@felipeleusin
Created September 24, 2015 16:21
Show Gist options
  • Select an option

  • Save felipeleusin/4f929025f75a26ccac28 to your computer and use it in GitHub Desktop.

Select an option

Save felipeleusin/4f929025f75a26ccac28 to your computer and use it in GitHub Desktop.
RavenMetadataListener
public class RavenMetadataToProperyListener : IDocumentConversionListener {
private static readonly ConcurrentDictionary<Type, RavenMetadataReflection[]> Cache = new ConcurrentDictionary<Type, RavenMetadataReflection[]>();
private static readonly MethodInfo JTokenValueMethod = typeof (RavenJToken).GetMethod("Value", new Type[] {});
public void BeforeConversionToDocument(string key, object entity, RavenJObject metadata)
{
}
public void BeforeConversionToEntity(string key, RavenJObject document, RavenJObject metadata)
{
}
public void AfterConversionToDocument(string key, object entity, RavenJObject document, RavenJObject metadata)
{
var properties = Cache.GetOrAdd(entity.GetType(), GetProperties);
foreach (var property in properties)
{
document.Remove(property.Member.Name);
}
}
public void AfterConversionToEntity(string key, RavenJObject document, RavenJObject metadata, object entity)
{
var properties = Cache.GetOrAdd(entity.GetType(), GetProperties);
foreach (var property in properties)
{
RavenJToken metadataProperty;
if (metadata.TryGetValue(property.MetadataField, out metadataProperty))
{
var memberType = property.Member.Type();
var metadataField = JTokenValueMethod.MakeGenericMethod(memberType).Invoke(metadataProperty, null);
property.SetValue(entity, metadataField);
}
}
}
private RavenMetadataReflection[] GetProperties(Type type)
{
var attrType = typeof(RavenMetadataAttribute);
return ReflectionUtil.GetPropertiesAndFieldsFor(type, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(p => Attribute.IsDefined(p, attrType))
.Select(pi => new RavenMetadataReflection(pi, (RavenMetadataAttribute)Attribute.GetCustomAttribute(pi, attrType)))
.ToArray();
}
}
public class RavenMetadataReflection
{
public MemberInfo Member { get; private set; }
public string MetadataField { get; private set; }
public RavenMetadataReflection(MemberInfo member, RavenMetadataAttribute metadataAttribute)
{
Member = member;
MetadataField = metadataAttribute.MetadataField;
}
public void SetValue(object entity, object value)
{
Member.SetValue(entity, value);
}
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class RavenMetadataAttribute : Attribute
{
public readonly string MetadataField;
public RavenMetadataAttribute(string metadataField)
{
MetadataField = metadataField;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment