ReflectionCache
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace NJsonSchema.Infrastructure
{
internal static class ReflectionCache
{
public class Property
{
public PropertyInfo PropertyInfo { get; }
public CustomAttributes CustomAttributes { get; }
public Property(PropertyInfo propertyInfo, CustomAttributes customAttributes)
{
PropertyInfo = propertyInfo;
CustomAttributes = customAttributes;
}
public string GetName()
{
if (CustomAttributes.JsonPropertyAttribute != null && !string.IsNullOrEmpty(CustomAttributes.JsonPropertyAttribute.PropertyName))
return CustomAttributes.JsonPropertyAttribute.PropertyName;
if (CustomAttributes.DataContractAttribute != null) {
dynamic val = CustomAttributes.DataMemberAttribute != null;
if ((val ? false : true) ? val : (val & !string.IsNullOrEmpty(CustomAttributes.DataMemberAttribute.Name)))
return (string)CustomAttributes.DataMemberAttribute.Name;
}
return PropertyInfo.Name;
}
}
public class CustomAttributes
{
public JsonIgnoreAttribute JsonIgnoreAttribute { get; }
public JsonPropertyAttribute JsonPropertyAttribute { get; }
public Attribute DataContractAttribute { get; }
public dynamic DataMemberAttribute { get; }
public CustomAttributes(JsonIgnoreAttribute jsonIgnoreAttribute, JsonPropertyAttribute jsonPropertyAttribute, Attribute dataContractAttribute, Attribute dataMemberAttribute)
{
JsonIgnoreAttribute = jsonIgnoreAttribute;
JsonPropertyAttribute = jsonPropertyAttribute;
DataContractAttribute = dataContractAttribute;
DataMemberAttribute = dataMemberAttribute;
}
}
private static readonly Dictionary<Type, IList<Property>> PropertyCacheByType = new Dictionary<Type, IList<Property>>();
private static readonly Dictionary<Type, Attribute> DataContractAttributeCacheByType = new Dictionary<Type, Attribute>();
public static IEnumerable<Property> GetProperties(Type type)
{
lock (PropertyCacheByType) {
if (!PropertyCacheByType.ContainsKey(type)) {
List<Property> value = (from p in type.GetRuntimeProperties()
select new Property(p, GetCustomAttributes(p))).ToList();
PropertyCacheByType[type] = value;
}
return PropertyCacheByType[type];
}
}
private static CustomAttributes GetCustomAttributes(PropertyInfo property)
{
JsonIgnoreAttribute jsonIgnoreAttribute = null;
JsonPropertyAttribute jsonPropertyAttribute = null;
Attribute dataMemberAttribute = null;
foreach (Attribute customAttribute in property.GetCustomAttributes()) {
if (customAttribute is JsonIgnoreAttribute)
jsonIgnoreAttribute = (customAttribute as JsonIgnoreAttribute);
else if (customAttribute is JsonPropertyAttribute) {
jsonPropertyAttribute = (customAttribute as JsonPropertyAttribute);
} else if (customAttribute.GetType().get_Name() == "DataMemberAttribute") {
dataMemberAttribute = customAttribute;
}
}
return new CustomAttributes(jsonIgnoreAttribute, jsonPropertyAttribute, GetDataContractAttribute(property.DeclaringType), dataMemberAttribute);
}
public static Attribute GetDataContractAttribute(Type type)
{
lock (DataContractAttributeCacheByType) {
if (!DataContractAttributeCacheByType.ContainsKey(type)) {
Attribute value = type.GetTypeInfo().GetCustomAttributes().SingleOrDefault((Attribute a) => a.GetType().get_Name() == "DataContractAttribute");
DataContractAttributeCacheByType[type] = value;
}
return DataContractAttributeCacheByType[type];
}
}
}
}