Google
 

Friday, June 01, 2007

Custom Business Object Implemented in C#


using  System;
using System.Collections.Generic;
using  System.Text;
using System.Data;
using System.Collections ;
using System.Reflection;

namespace COW.Business
{
    
/// <summary>
    
/// The Custom Business Object is used to fill business object or objects with IDataReader
    
/// The properties will be cached once they have been retrieved
    
///  </summary>
    public  class CBO<T>
    {
        
public CBO()
        { }
        
///  <summary>
        
/// Using reflectiong, to fill object with data in data reader
        
/// </summary>
        
/// <param name="reader"></param>
        
/// <param name="isManagedReader"> If the data reader is managed by others</param>
        
///  <returns></returns>
         public  T FillObject(IDataReader reader,bool isManagedReader)
        {
            
if (reader ==  null)
                
return default (T);

            
try
            {
                
//  get properties 
                IList<PropertyInfo > properties = RetrieveProperties();
                
// confirm each property index in data reader
                IList<int> ordinals  = GetOrdinal(reader, properties);
                
// check if data reader is managed
                if (isManagedReader)
                {
                    
return CreateObject(reader, properties, ordinals);
                }
                
else
                {
                    
try
                    {
                        
while (reader.Read())
                        {
                            
return  CreateObject(reader, properties, ordinals);
                        }
                        
throw  new Exception("The data read is null! ");
                    }
                    
finally
                    {
                        
if (reader !=  null)
                        {
                            reader.Close();
                        }
                    }
                }
            }
            
catch (Exception ex)
            {
                COW.Common.Exceptions.LogException(ex);
                
return default(T);
            }            
        }
        
/// <summary>
        
///  Using reflectiong, to fill object with data in data reader
        
/// The reader is not managed by others
        
/// </summary>
        
/// <param name="reader"></param>
        
/// <returns></returns>
        public T FillObject(IDataReader reader)
        {
            
return FillObject(reader,false);
        }

        
private T CreateObject(IDataReader reader, IList<PropertyInfo > properties, IList<int>  ordinals)
        {
            T target 
= Activator.CreateInstance< T>();
            
object propertyValue  = null;
            
// create an object instace and set each property with its value in data reader
             for (int i  = 0; i <  properties.Count; i++)
            {                
                
if  (-1 == ordinals[i])
                {
                    
// the property is not existing in data reader
                    continue;
                }
                PropertyInfo property 
= properties[i];
                
if ( !property.CanWrite)
                {
                    
// the property is readonly
                    continue;
                }
                
// set writable propertiy's value           
                try
                {
                    
//  set db null value                    
                    if  (reader[ordinals[i]].GetType().Equals( typeof(System.DBNull)))
                    {
                        property.SetValue(target,
null,null);
                    }
                    
else
                    {                    
                        
//  implicitly convert
                        property.SetValue(target, reader[ordinals[i]],  null);                    
                    }                    
                }
                
catch
                {
                    Type propertyType 
= property.PropertyType;
                    
// business object member type does not match the data member's type
                    
//  TODO: here to handle the enumeration type 
                    
// try explicitly convert                
                    
// if the type is nullable
                     if (propertyType.IsGenericType)
                    {
                        property.SetValue(target, Convert.ChangeType(reader[ordinals[i]],  propertyType.BaseType), 
null);
                    }
                    
else  if (propertyType.IsEnum)
                    { 
                        
//  nothing
                    }
                    
else
                    {
                        property.SetValue(target, Convert.ChangeType(reader[ordinals[i]], propertyType), 
null );
                    }
                }
            }
            
// return the object
            return target;
        }
        
/// <summary>
        
///  Get the property's index order in data reader
        
///  </summary>
        
/// <param name="reader"></param>
        
/// <param name="properties"></param>
        
/// <returns></returns>
        private List <int> GetOrdinal(IDataReader reader, IList< PropertyInfo> properties)
        {            
            
// check property name
            List< int> ordinals =  new List<int >();
            
if (reader !=  null)
            {
                
for ( int i = 0 ; i < properties.Count; i++ )
                {
                    
int ordinal =  -1;
                    
try
                    {
                        ordinal 
= reader.GetOrdinal(properties[i].Name);
                    }
                    
catch
                    { }  
                    ordinals.Add(ordinal);
                }
            }
            
return ordinals;
        }
        
///  <summary>
        
/// Using reflection, to fill a collection of object with data in data reader
        
/// </summary>
        
/// <param name="reader"></param>
        
/// <param name="objectType"></param>
        
/// <returns></returns>
        public  IList< T> FillCollection(IDataReader reader)
        {
            
//  create object collection
            List<T > collection =  new List<T> ();
            
if (reader ==  null)
            {
                
return collection;
            }
            
try
            {
                
while (reader.Read ())
                {
                    
// foreach item in data reader
                    
// fill an object with the item
                    T target  = FillObject(reader, true);
                    
// add the filed object to collection
                    collection.Add(target);
                }
                
if (reader !=  null)
                {
                    reader.Close();
                }
                
//  return the collection
                return collection;
            }
            
catch (Exception ex)
            {
                COW.Common.Exceptions.LogException(ex);
                
return collection;
            }
            
        }
        
///  <summary>
        
/// Retrieve the properties of T by reflection
        
/// </summary>
        
/// <param name="t"></param>
        
/// <returns></returns>
        private static  IList<PropertyInfo> RetrieveProperties()
        {
            
// get object properties in cache
            List<PropertyInfo> properties  = (List<PropertyInfo >)Cache.GetObject(typeof(T).FullName);

            
// retrieve object properties when that are not cached
             if (properties == null )
            {
                properties 
= new  List<PropertyInfo>();
                
foreach (PropertyInfo property in  typeof(T).GetProperties())
                {
                    properties.Add(property);
                }
                
//properties.AddRange(typeof(T).GetProperties);
                
// cache it
                Cache.SetObject(typeof(T).FullName, properties);
            }
            
return properties;
        }
    }
}


--
Happy day, happy life!

No comments: