views:

77

answers:

2

I want to implement a simple attribute that is used to map Database Columns to Properties.

So what i have so far is something that attached like so:

 [DataField("ID")]
 public int ID { get; set; }

 [DataField("Name")]
 public String Name { get; set; }

 [DataField("BirD8")]
 public DateTime BirthDay { get; set; }

Is there a way that I can make the attribute "aware" of the field it is on, so that for the properties where the name is the same as the ColumnName I can just apply the attribute without the name parameter, or would I have to deal with that at the point where I reflect the properties. I want to end up doing just this:

 [DataField]
 public int ID { get; set; }

 [DataField]
 public String Name { get; set; }

 [DataField("BirD8")]
 public DateTime BirthDay { get; set; }
+3  A: 

The attribute itself won't be aware of what it's applied to, but the code processing the attributes is likely to be running through PropertyInfo values etc and finding the attributes associated with them. That code can then use both the property and the attribute appropriately.

To make things simpler, you might want to write a method on the attribute to allow it to merge its information with the information from the property, so you'd call:

DataFieldAttribute dfa = propertyInfo.GetCustomAttributes(...); // As normal
dfa = dfa.MergeWith(propertyInfo);

Note that for the sake of sanity this should create a new instance of the attribute, rather than changing the existing one. Alternatively, you might want a whole separate class to represent "the information about a data field":

DataFieldAttribute dfa = propertyInfo.GetCustomAttributes(...); // As normal
DataFieldInfo info = dfa.MergeWith(propertyInfo);

That way you could also construct DataFieldInfo objects without any reference to attributes, which might be a nice conceptual separation - allowing you to easily load the config from an XML file or something similar if you wanted to.

Jon Skeet
There is just a problem when you don't own the code processing the attributes. We face this problem with localization attributes, it could also be an issue in validation attributes and others. We have some attributes where we need to pass the name of the property and the type of the class it is defined on as argument - which is really bad.
Stefan Steinegger
If you don't own the code processing the attributes, then presumably it has been designed assuming the restrictions that attributes always have - namely that you can't access the target. I agree it's a bit of a pain.
Jon Skeet
Thanks. I managed to crowbar in a solution where I was reflecting the attribute.
My Other Me
+1  A: 

If you don't mind using postsharp you can look Here, at a previous question I have asked which was close. I ended up using the compile time validate to do what I wanted, although there are other options, like CompileTimeInitalize.

public override void CompileTimeInitialize(object element)
{
    PropertyInfo info = element as PropertyInfo;

    //....
}
Courtney de Lautour
Thanks. I could not use this approach here, but I now know that postsharp exists and what it can do. Much appreciated.
My Other Me