Library tutorials & articles
Attributed Programming in .NET Using C#
- Introduction
- Intrinsic and Custom Attributes
- Attribute Targets and Specifications
- Implementing a Custom Attribute
- Implementing a Custom Attribute contd
- Under the hood
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.
Related articles
Related discussion
-
Binary Studio | software development outsourcing Ukraine
by shane124 (4 replies)
-
Chart insertation in a windows form...
by pdhanik (1 replies)
-
Point of Sale Developers: Hardware & C# SDK
by ManiGovindan (7 replies)
-
help with the remote frame buffer protocol from real VNC
by poison (0 replies)
-
Need help making a complete program editable, C# or .net I think
by davelee (1 replies)
Related podcasts
-
A Practical Look at Silverlight 2 Part 1
Now that Silverlight 2 is at the Olympics and making a big splash, we wanted to explore this fascinating technology more. Microsoft Silverlight 2 is a cross-browser, cross-platform, and cross-device plug-in for delivering the next generation of .NET based media experiences and rich interactive ap...
Events coming up
-
Dec
9
GL.net Group Meeting - December 2009
Gloucester, United Kingdom
The beginning of this year holiday season will belong to mocks. Ronnie and Stephen will take us for a tour around exciting world of unit testing.
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 understand simple using [SERIALIZABLE] makes life easier, but to really appreciate this perhaps I would want to understand whats the tought way of doing the same.
Could anybody explain with an example how attribute is giving ab advantage.
Thanks
sourabh
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 using private and was unable to get it to work.
I have absolutely no knowledge of C# and attributes, but I could understand the article very easily. Good Write-up!
The advantages provided with attributed programming is amazing and simultaneously it has a drawback.
The growth of attributes in each model like MIDL,MTS/COM+ and .NET is quite alarming.It increases the learning curve for a developer to use that Runtime.
And it seems whatever the runtime Environment is not able to do is kept as attributes and Developer has to provide it.
For example
void GetData(CMyObject obj1,CMyObject &obj2);
In the above method all C++ compiler recognizes that obj1 is passed by value and obj2 is passed by reference.If the Runtime environment can have the equivalent inteligence then no requirement of marking [SERIALIAZABLE] attribute to the class if we want to pass the object by value.
And what ever feature is not provided by any of the existing Object Oriented Language can be used as attributes.
Ghanshyam.
The article is nice
This thread is for discussions of Attributed Programming in .NET Using C#.