Struggling for Competence

C# Custom Attributes

We had a problem where a class was supplying data to the UI through a list. The UI had to know which properties in the class were the supplying data. I decided to use custom attributes to identify the properties. With some help of some code from my colleague Barry, I knocked up this sample to define and get the attributes. The Ordinal property is used to order the data series. C#, Custom Attribute [1], Reflection [2].


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MbUnit.Framework;
using System.Reflection;

namespace AttributeDemo
{
    [TestFixture]
    public class AttributeDemoTest
    {
        [AttributeUsage(AttributeTargets.Property)]
        public class Series : Attribute
        {
            public string PropertyName { get; set; }
            public int Ordinal { get; set; }

            public Series(int ordinal)
            {
                this.Ordinal = ordinal;
            }

            public static List<Series> GetSeries(Type type)
            {
                List<Series> allSeries = new List<Series>();
                foreach (PropertyInfo property in type.GetProperties())
                {
                    foreach (Attribute attribute in property.GetCustomAttributes(false))
                    {
                        if (attribute is Series)
                        {
                            Series series = (Series)attribute;
                            series.PropertyName = property.Name;
                            allSeries.Add(series);
                        }
                    }
                }
                return allSeries;
            }
        }

        class AttributeExample
        {
            [Series(1)]
            public string WarnCount { get; set; }
            [Series(2)]
            public string ErrorCount { get; set; }
        }

        [Test]
        public void GetSeries_ShouldReturnTheSeriesAttributesFromTheType()
        {
            List<Series> allSeries = Series.GetSeries(typeof(AttributeExample));
            Assert.AreEqual(2, allSeries.Count);

            Series actual = allSeries.Find(s => s.Ordinal == 2);
            Assert.AreEqual(2, actual.Ordinal);
            Assert.AreEqual("ErrorCount", actual.PropertyName);
        }
    }
}