Send a suggestion!

We're building a brand new version of the site, and we'd love to hear your ideas

Members

Technology Zones

IBM Learning Center

Articles

Hosted By

MaximumASP

Info

Rated
Read 36,696 times

Contents

Related Categories

Attributed Programming in .NET Using C# - Implementing a Custom Attribute contd

ddutta

Implementing a Custom Attribute contd

A custom attribute class should be derived from the base class Attribute defined in System namespace and housed in mscorlib.dll assembly. By convention, name of an attribute class is postfixed with "Attribute" and the suffix "Attribute" can be dropped when the custom attribute is applied to a target. Using this convention, we define our custom attribute as:

[AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]
public class ValidLengthAttribute : Attribute{
    private int _min;
    private int _max;
    private string _message;

    public ValidLengthAttribute(int min,int max){
         _min=min;
         _max=max;
    }

    public string Message{
         get {return(_message);}
         set {_message=value;}
    }

    public string Min{
         get{return _min.ToString();}
    }

    public string Max{
         get{return _max.ToString();}
    }

    public bool IsValid(string theValue){
         int length=theValue.Length;
         if(length >= _min && length <= _max) return true;
         return false;
    }
}

The custom attribute definition is mostly self-explanatory, however, we will discuss a few things before we proceed to define our Validator class. Like any other class, a custom attribute class can be a target of other attributes as we have in the definition above. The attribute AttributeUsage specifies the type of targets the attribute can be applied to. A custom attribute class should be public. By default, the custom attribute defined above can only be used once per target.

The Validator class to validate an object is defined as:

public class Validator{
    public ArrayList Messages=new ArrayList();

    public bool IsValid(object anObject){
         bool isValid=true;
         FieldInfo[] fields = anObject.GetType().GetFields(BindingFlags.Public|BindingFlags.Instance);
              foreach (FieldInfo field in fields)
                   if(!isValidField(field,anObject)) isValid=false;
              return isValid;
    }

    private bool isValidField(FieldInfo aField,object anObject){
         object[] attributes=aField.GetCustomAttributes(typeof(ValidLengthAttribute),true);
         if(attributes.GetLength(0) ==0) return true;
         return isValidField(aField,anObject,(ValidLengthAttribute)attributes[0]);
    }

    private bool isValidField(FieldInfo aField, object anObject,ValidLengthAttribute anAttr){
         string theValue=(string)aField.GetValue(anObject);
         if (anAttr.IsValid(theValue)) return true;
         addMessages(aField,anAttr);
         return false;
    }

    private void addMessages(FieldInfo aField,ValidLengthAttribute anAttr){
         if(anAttr.Message !=null){
              Messages.Add(anAttr.Message);
              return;
         }
         Messages.Add("Invalid range for "+aField.Name+". Valid range is between "+anAttr.Min+" and "+anAttr.Max);
    }
}

The Validator class uses reflection classes to validate the object passed as a parameter to its IsValid method. First, it extracts all the public fields in the object using GetType().GetFields(BindingFlags.Public|BindingFlags.Instance) method. For each field, it extracts the custom attribute of type ValidLengthAttribute using GetCustomAttributes(typeof(ValidLengthAttribute),true). If it does not find our custom attribute for a field, it assumes the field to be valid. If it finds our custom attribute for a field, it calls the IsValid method of ValidLengthAttribute to validate the value of the field.

Comments

  • Why attribute

    Posted by soruabhm on 03 May 2004

    Hi
    Good article.I have a qus here. I have used a ot of attributes and have tried writing mine as well. Now the basic qus of when to write one of our own is still a little difficult for me. I understa...

  • Serialization SOAP

    Posted by zaka48 on 06 Mar 2004

    how can I Add a reference to assembly System.Runtime.Serialization.Formatters.Soap.dll ???

  • Private attributes in .Net c#?

    Posted by nguyen422 on 10 Jan 2003

    This is a very good article.

    The example shown used public modifier for the class attributes, is there any way to get it to work with private/protected attributes? I tried the example code usin...

  • Attributes

    Posted by chinnu704 on 06 Jan 2003

    I have absolutely no knowledge of C# and attributes, but I could understand the article very easily. Good Write-up!

  • Drawbacks of attributed programming

    Posted by ghanshyam on 12 Nov 2002

    Well the attributed programming started from MIDL/COM programming and .NET also supports this concept widely.
    The advantages provided with attributed programming is amazing and simultaneously it has ...