Reflection is an interesting topic. Code describing itself? Code looking at and examining other code? Well that pretty much describes what reflection is. First of I have to give thanks to my good friend Brady Gaster for turning me on to reflection. In fact what I've implemented here is actually his idea, and I've just gone a bit farther with it, then what he originally showed me.
So what is reflection? Lets take a look at intellisense for just a second. How in the world is Visual Studio so smart? You create a class, and it immediately shows up in intellisense. Ever wondered how that works? We'll it's not simply magic as some of you might have thought. Visual Studio looks at your code, or you might say "Reflects" upon your code, using reflection.
OK, OK, to the point. Aren't most of the data classes created in a project able to be directly mapped to tables in a SQL server. So here's an idea; mark each property of a class, and the class it self with attributes. These attributes can then be discovered through reflection. An attribute is nothing more then a class that can have it's own properties, constructors, and methods. Think about having a class specifically to describe each property in your class. Here's an example.
[DatabaseColumn("Address")]
public string Address()
{
Get { ... }
Set { ... }
}
and the Attribute is defined as a class that inherits from Attribute, and looks something like this...
[AttributeUsage(AttributeTargets.Property)]
public class DatabaseColumnAttribute : Attribute
{
public DatabaseColumnAttribute(string ColumnName)
{
this.columnName = ColumnName;
}
private string columnName;
public string ColumnName
{
get { return this.columnName; }
set { this.columnName = value; }
}
}
So here's what my reflection data access layer does. Although the solution you're about to read about makes your project tightly coupled with SQL server, the "ObjectManager" could easily be modified to use a provider model.
Each class is marked with an attribute letting the "ObjectManger" know what table in the database is going to be used for the class. Then each property has an attribute, that the "ObjectManager" uses to figure out how to Select, Update, Delete, and Create each object.
The available object types are all of the SQL data types, and I included support for a Hashtable. A Hashtable is basically an array of key/value pairs. the HashtableAttribute takes a single parameter of type int, and that is used in the select phase and maps to a specific result set in a data reader. This works great for populating an object, but it currently does not work for updates, the Hashtable property is totally ignored for everything except Select Statements.
I'm happy to answer questions you may have on this project, and I'll continue to work on it, to make it better and better. My e-mail address is at the top of this page if you have any questions.
Oh, one last thing. This project is not exclusive to this reflection layer. There are some other miscellaneous pages that I've used in a User Control Master Page idea, error handling, an IHttpPageHandlerFactory, and whatever else may be in there. If you're looking into the reflection piece, you'll mainly want to focus on /Lib/Attributes/*.*, and /Lib/DataAccess/*.*.