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

Accessing and caching attributes

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

Problem

I have the following manager class that handles access and caching attributes from classes. I am a bit worried about the caching mechanism.

Is there a better way of handling it?

public static class AttributeManager
    {
        private static Dictionary _cache = new Dictionary();

        public static AttributeType GetAttribute(Type type)
            where AttributeType : Attribute
        {

            if (_cache.ContainsKey(type))
            {
                return (AttributeType)_cache[type];
            }

            var attr = Attribute.GetCustomAttribute(type, typeof(AttributeType));

            if (attr != null)
            {
                _cache.Add(type, attr);
                return (AttributeType)attr;
            }
            else
            {
                throw new ArgumentException($"The specified attribute: {nameof(AttributeType)} was not found.");
            }
        }
    }

Solution

Let’s define an extension method on Type:

public static class AttributeCache
{
    public static IEnumerable Attributes(this Type type)
        where T : Attribute => Cache
            .GetOrAdd(type, t => t.GetCustomAttributes(true).OfType().ToArray())
            .OfType();        

    static ConcurrentDictionary Cache { get; } = 
        new ConcurrentDictionary();
}


Demo:

foreach (var a in typeof(MyCass).Attributes())
    Console.WriteLine(a.MyProp);

Code Snippets

public static class AttributeCache
{
    public static IEnumerable<T> Attributes<T>(this Type type)
        where T : Attribute => Cache
            .GetOrAdd(type, t => t.GetCustomAttributes(true).OfType<Attribute>().ToArray())
            .OfType<T>();        

    static ConcurrentDictionary<Type, Attribute[]> Cache { get; } = 
        new ConcurrentDictionary<Type, Attribute[]>();
}
foreach (var a in typeof(MyCass).Attributes<TestAttribute>())
    Console.WriteLine(a.MyProp);

Context

StackExchange Code Review Q#131861, answer score: 6

Revisions (0)

No revisions yet.