Generic Object Mapper

We were connecting to a DB2 database through our ASP.NET application.So we decided to use IBM.Data.DB2 dll and added DB2DataAccess and DB2DataReaderHelper classes.Everything was set and we started constructing our Data Access Layer, keeping our approach simple - connect to the database, get a datareader / dataset,use a mapper method to populate our custom classes / business entities with the data and close the connection.Slowly the number of mapper methods grew.Considering the fact that we had around 111 Business Entity Classes and even if we had to populate 50 % of these classes from the DB and some cases we could map more than one classes together in single method, we would still land up in around 40-50 mapper methods.So we did a bit of an introspection to understand if writing those many mapper methods was worthwhile our effort and time, not ignoring the fact it could make our lives hell during maintenance.

Hence the idea of writing a generic object mapper dawned.So we wrote one using reflection which could just have two methods - MapObject & MapObjectList - one returned a single instance and other returned a list of objects. Both methods took datareader as input parameter. We later added two more overloaded methods for dataset as well.So here is how our code looked like:

using System;
using System.Linq;
using System.Reflection;
using System.Diagnostics;
using System.Collections.Generic;

using IBM.Data.DB2;
namespace DataAccessLayer
{
public static class ObjectMapper
{
private const string COLUMN_NAME = "ColumnName";
private const string EQUAL_TO = "= ";
private const string SINGLE_QUOTE = "'";
///


/// Reads a row from Data Reader and maps to the Object Instance.
///

/// Type to map to
/// Data Reader/// Instance of Type T
public static T MapObject(DB2DataReader dataReader)
{
T objectToMapTo = Activator.CreateInstance();
PropertyInfo[] properties = typeof(T).GetProperties();
if (dataReader != null)
{
while (dataReader.Read())
{
for (int i = 0; i < properties.Length; i++)
{
if (CheckIfColumnExists(dataReader, properties[i].Name)
&&dataReader[properties[i].Name] != DBNull.Value) typeof  (T).InvokeMember(properties[i].Name, BindingFlags.SetProperty, null, objectToMapTo, new Object[] { dataReader[properties[i].Name] }); } } } return objectToMapTo; } ///
/// Checks if Column Exists in the Data Reader.
///

/// Data Reader/// Column Name/// A flag indicating if column exists in Data Reader
private static bool CheckIfColumnExists(DB2DataReader dataReader, string columnName)
{
dataReader.GetSchemaTable().DefaultView.RowFilter = COLUMN_NAME + EQUAL_TO + SINGLE_QUOTE + columnName.ToUpper() + SINGLE_QUOTE;
return (dataReader.GetSchemaTable().DefaultView.Count > 0);
}
///
/// Returns a list of mapped objects.
///

/// Type to return
/// Data Reader/// Returns a list of mapped objects
public static IList MapObjectList(DB2DataReader dataReader)
{
IList objectList = new List();
if (dataReader != null)
{
while (dataReader.Read())
{
objectList.Add(MapObject(dataReader));
}
}
return objectList;
}
}
}

Comments

Popular posts from this blog

Technical Interview Screen

Natural Face Pack

Cloud Drives