Skip to content

Instantly share code, notes, and snippets.

@pinscript
Created August 24, 2011 07:19
Show Gist options
  • Save pinscript/1167473 to your computer and use it in GitHub Desktop.
Save pinscript/1167473 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace ConsoleApplication12 {
class Program {
static void Main(string[] args) {
var sw = new Stopwatch();
var iterations = 50000;
// Warmup
AttributeRetriever.GetAttribute<Model, string>(x => x.Name, typeof (PrivilegeAttribute), "Privilege");
sw.Start();
for(var i = 0; i < iterations; i++) {
AttributeRetriever.GetAttribute<Model, string>(x => x.Name, typeof(PrivilegeAttribute), "Privilege");
}
sw.Stop();
Console.WriteLine("Took {0} ms", sw.ElapsedMilliseconds);
Console.Read();
}
}
class AttributeRetriever {
private static Dictionary<ICustomTypeDescriptor, PropertyDescriptor> _descriptorCache = new Dictionary<ICustomTypeDescriptor, PropertyDescriptor>();
public static string GetAttribute<TModel, TProperty>(Expression<Func<TModel, TProperty>> exp, Type attributeType, string attributePropertyName) {
var memberExpression = (MemberExpression)exp.Body;
var propertyName = memberExpression.Member.Name;
var containerType = memberExpression.Expression.Type;
var typeDescriptor = new AssociatedMetadataTypeTypeDescriptionProvider(containerType).GetTypeDescriptor(containerType);
PropertyDescriptor property;
if(!_descriptorCache.TryGetValue(typeDescriptor, out property)) {
property = typeDescriptor.GetProperties().Find(propertyName, true);
_descriptorCache[typeDescriptor] = property;
}
var attributes = property.Attributes.Cast<Attribute>();
var attribute = GetAttribute(attributes, attributeType);
var value = GetAttributeValue(attribute, attributePropertyName);
return value.ToString();
}
private static Dictionary<Type, PropertyInfo> _attributeCache = new Dictionary<Type, PropertyInfo>();
private static object GetAttributeValue(Attribute attribute, string attributePropertyName) {
var attributeType = attribute.GetType();
PropertyInfo property;
if(!_attributeCache.TryGetValue(attributeType, out property)) {
property = attributeType.GetProperty(attributePropertyName, BindingFlags.Instance | BindingFlags.Public);
_attributeCache[attributeType] = property;
}
return property.GetValue(attribute, null);
}
private static Attribute GetAttribute(IEnumerable<Attribute> attributes, Type attributeType) {
return attributes.FirstOrDefault(x => x.GetType().Equals(attributeType));
}
}
class Model {
[Description("Namn")]
[Privilege(Privilege.User)]
public string Name { get; set; }
}
enum Privilege {
Admin = 1,
User
}
internal class PrivilegeAttribute : Attribute {
public Privilege Privilege { get; set; }
public PrivilegeAttribute(Privilege privilege) {
Privilege = privilege;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment