Steve Eichert posed an interesting question regarding O/R mappers and the use (or lack thereof) of attributes to define the details of mapping business entities to relational database tables. He specifically asked why attributes are good enough for Indigo, but not for O/R mappers? Paul Wilson, the creator of WilsonORMapper (which I think is currently one of the best mappers in the .NET world) replied with a couple of points describing why he prefers to use XML:
- Persistence is external to my entity objects — I can and do use my entities differently at times.
- Makes it easier to change the O/R Mapper I use — not totally seamless, but easier if pure POCO.
- Table and field names can and do vary at times — customers of my apps do have different schemas.
- Makes it easier to reuse my entity objects — the same business logic can be used in different ways.
- Personal preference — focus on business only — I just don’t see the point of attribute clutter.
While I’m certainly not opposed to either approach, and think that each has its merits, I believe that the benefits of an attribute-based approach are somewhat under-represented. I also think they are misrepresented in several ways as well. I’ll offer up this point by point breakdown:
“Persistence is external to my entity objects — I can and do use my entities differently at times.”
Persistence is indeed external to the inner workings of a business object. However, attributes are metadata, and do not define any behaviour. Marking a business object as [Serializable()] is exactly the same. The fact that it can be serialized has nothing to do with the business object. You’re just marking it for some other process, in case this information might be useful elsewhere. There is no difference.
“Makes it easier to change the O/R Mapper I use — not totally seamless, but easier if pure POCO.”
I’m willing to tag this argument as YAGNI. Using XML because you might switch out an O/R mapper for another is stretching things somewhat.
“Table and field names can and do vary at times — customers of my apps do have different schemas.”
This can easily be done using attributes as well. [TableColumn("databaseColumnName")] does this nicely.
“Makes it easier to reuse my entity objects — the same business logic can be used in different ways.”
Once again, attributes are just metadata. They should have absolutely no bearing on how an object is actually used. Unless you’re doing something completely wacky with your attributes (like basing business functionality on them), this argument doesn’t hold water.
“Personal preference — focus on business only — I just don’t see the point of attribute clutter.”
Point granted. Attributes can clutter up a class file to some degree. But the flip side of this, is that it’s easy to see anything related to your object at a glance if you use attributes, by going to the source file. Everything you need is right there, in one place, not spread out over multiple files. This is an often overlooked point in my mind.
So there you have it. In my mind, it really does just boil down to personal preference (or the preference of the dude writing the O/R mapper). Do you want all your information in one place where it’s easily accessible, or spread out over multiple files to keep things nice and tidy? Take your pick.