Introduction
With the insertion of Generics in the 2.0 Framework, developers have a tool that radically changes the way to develop. Some of the main advantages of using Generics are:
- Type Safety
- Intellisense support
- Reduction of repetitive code
- Collections with great functionality included (
Collection
s, List
, Queue
, Stack
, LinkedList
)
Background
In almost all applications, it's necessary to persist the state of the instances of the objects that we use soon to be consulted and to regenerate these instances. This process of regeneration generally implies great amount of code, nontyped collections, that result in error sensible code and smaller performance. In this simplified example of a data access layer, we will see that it is possible to obtain an instance or list of instances of any entity with only two generic methods.
Generics Methods
To fill one instance:
public static void PopulateEntity<T>(T entity, IDataRecord record)
{
if (record != null && record.FieldCount > 0)
{
Type type = entity.GetType();
for (int i = 0; i < record.FieldCount; i++)
{
if (DBNull.Value != record[i])
{
PropertyInfo property =
type.GetProperty(record.GetName(i),
BindingFlags.IgnoreCase |
BindingFlags.Public | BindingFlags.Instance);
if (property != null)
{
property.SetValue(entity,
record[property.Name], null);
}
}
}
}
}
To fill an instance List
:
public static List<T> PopulateEntities<T>(IDataReader dr)
{
List<T> entities = new List<T>();
while (dr.Read())
{
T ent = Activator.CreateInstance<T>();
PopulateEntity<T>(ent, dr);
entities.Add(ent);
}
return entities;
}
Using the Methods
If we need a single instance of one entity, invoke the method PopulateEntity
passing as parameter the entity type, an empty instance and a record of a Datareader
.
public static Contact getContactById(int id)
{
Contact contact = new Contact();
Database db = DatabaseFactory.CreateDatabase();
DbCommand dbCommand = db.GetStoredProcCommand("ContactById");
db.AddInParameter(dbCommand, "contactId", DbType.Int32, id);
IDataReader idr = db.ExecuteReader(dbCommand);
if (idr.Read())
{
EntityUtils.PopulateEntity<Contact>(contact, idr);
}
return contact;
}
If we need an instance collection of one entity, invoke the method PopulateEntities
passing as parameter the entity type and Datareader
.
public static List<Contact> getContacts()
{
Database db = DatabaseFactory.CreateDatabase();
DbCommand dbCommand = db.GetStoredProcCommand("ContactGetAll");
IDataReader idr = db.ExecuteReader(dbCommand);
return (EntityUtils.PopulateEntities<Contact>(idr));
}
Using generics List
as return of PopulateEntities
we have an instance collection with methods having great functionality to sort, find, iterate, manage in our business and user interface layers.
Configure the Sample Project
The sample uses the AdventureWorks
database included in SQL Server 2005. Modify the connection string LocalSqlServer located in web.config and run the script StoredProcedures.sql located in the App_Data directory to add the necessary stored procedures.
Conclusion
The inclusion of Generics in the Framework produced a jump of maturity and productivity to this tool. Therefore I consider that is one of the aspects in which it is necessary to deepen knowledge, otherwise we will lose an easy and advantageous way to develop.
History
- 20th December, 2006: Initial post
About MartÃn Olivares
I'm an system engineer with 8 years of experience as a developer/architect in enterprise project solutions. I have always worked with Microsoft Platforms and technologies such as VB, SQL Server, .NET, MSF.