Using reflection and attributes



Reflection: Reflection provides objects (of type Type) that encapsulate assemblies, modules and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. If you are using attributes in your code, Reflection enables you to access them (Source: MSDN).

For a beginner even for moderate developer, reflection and use of attributes is always a nightmare. To use these features in your application, first of all you need to understand what they are; I assume that you having basic understanding of both of these features. Now let us understand the problem and see how it can be solved using reflection and attributes.

Let's take an example. There is a class user in one project which has properties/methods; some of the properties are for the Admin role of application and some are for the User role. There is another project in which you want to use Admin properties of that class. At the time of implementation you do not know the name of property and since it is a live application you do not want to change any of the properties.

To do this, I will use attribute feature. I will create an attribute class RoleType, which will have two properties Role and DefaultValue.

[AttributeUsage(AttributeTargets.All)]
    public class RoleType : System.Attribute
    {

        public RoleType(string role,bool defaultValue)
        {
            this._role = role;
            this._defaultValue = defaultValue;
        }
        private string _role;
     
  private bool _defaultValue;

        public string Role
        {
            get
            {
                return _role;
            }
            set
            {
                _role = value;
            }
        }

        public bool DefaultValue
        {
            get
            {
                return _defaultValue;
            }
            set
            {
                _defaultValue = value;
            }
        }

    }

Now add this attribute to the properties which belongs to the Admin role like below

[RoleType ("admin", true)]
        public bool CanCreateUser
        {
            set
            {
                canCreateUser = value;
            }
            get
            {
                return canCreateUser;
            }
        }

[RoleType ("admin", true)]
        public bool CanSendMassMail
        {
            set
            {
                canSendMassMail = value;
            }
            get
            {
                return canSendMassMail;
            }

        }

In the above code, CanCreateUser and CanSendMassMail belong to Admin role and have default value as true.

Now we are done half way; we added attribute to the properties which are for Admin role. The next step is to get all the properties which belong to the Admin role and to store those in some collection (in a datatable).

I will write a function and use reflection. I will iterate all the properties of object and get the value from there using
<objectName>.GetType().GetProperties(). GetType().GetProperties() will do the trick, this will return all the properties of object. I had created another function IsRoleTypeSet() to keep code cleaner which will be called by the GetPropertyFromAtribute function.


public DataTable GetPropertyFromAtribute(Users uc, bool getDefault)
        {
           
            //Datatable declaration
           
DataTable dt = new DataTable();
            DataColumn dcName = new DataColumn();
            DataColumn dcValue = new DataColumn();
            DataRow dr;
            ArrayList at;
            dcName.ColumnName = "Name";
            dcValue.ColumnName = "Value";
            dcName.DataType = System.Type.GetType("System.Boolean");
            dcValue.DataType = System.Type.GetType("System.Boolean");

            dt.Columns.Add(dcName);
            dt.Columns.Add(dcValue);           
            //Loop object to get the properties
            foreach (PropertyInfo method in uc.GetType().GetProperties())
            {
                at = new ArrayList();
                at = IsRoleTypeSet(method, uc, getDefault);
                if (at.Count != 0)
                {
                    dr = dt.NewRow();
                    dr["Name"] = method.Name;
                    dr["Value"] = Convert.ToBoolean(at[0]);
                    dt.Rows.Add(dr);
                }
            }
            return dt;
        }


In IsRoleTypeSet function, I will first check for the custom attribute which I had created using member.GetCustomAttributes(true) and then if my custom attibute is found I will get the default value or the assigned value based on flag GetDefault.
To get default value I will use (RoleType)attribute).DefaultValue and to get value in the property I will use uc.GetType().GetProperty(member.Name).GetValue(uc, null).ToString()


private ArrayList IsRoleTypeSet (PropertyInfo member, Users uc, bool GetDefault)
        {
            RoleType tempObj = new RoleType ("",false);
            ArrayList retValue = new ArrayList();
            foreach (Attribute attribute in member.GetCustomAttributes(true))
            {
                if (attribute is RoleType)
                {
                    retValue = new ArrayList();
                    if (GetDefault)
                    {
                        retValue.Add(((RoleType)attribute).DefaultValue);
                    }
                    else
                    {
                        retValue.Add(Convert.ToBoolean(uc.GetType().GetProperty(member.Name).GetValue(uc, null).ToString()));
                    }

                    return retValue;
                }
            }
            return retValue;
        }


uc.GetType().GetProperty(member.Name).GetValue(uc, null).ToString() is the beauty of reflection, where I will get the value even though I do not know the name of the property.


Similar Articles