public static T ExpandObject <T>(object o, Func <FieldInfo, IDataRecord, object> customApply) where T : class, new()
        {
            Type       t             = typeof(T);
            T          returnObject  = (T)o;
            string     dictionaryKey = string.Empty;
            SqlCommand sqlCommand;

            foreach (FieldInfo fieldInfo in returnObject.GetType().GetFields())
            {
                if (Attribute.IsDefined(fieldInfo, typeof(DictionaryMapAttribute)))
                {
                    DictionaryMapAttribute dictionaryMapAttribute = (DictionaryMapAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(DictionaryMapAttribute));
                    using (DataManager.Current.OpenConnection())
                    {
                        if (!dictionaryMapAttribute.IsStoredProcedure)
                        {
                            sqlCommand = DataManager.CreateCommand(dictionaryMapAttribute.Command);
                        }
                        else
                        {
                            sqlCommand = DataManager.CreateCommand(dictionaryMapAttribute.Command, CommandType.StoredProcedure);
                        }
                        foreach (SqlParameter param in sqlCommand.Parameters)
                        {
                            string fieldName = param.ParameterName.Substring(1);                             //without the "@"
                            param.Value = returnObject.GetType().GetField(fieldName).GetValue(returnObject);
                        }

                        fieldInfo.SetValue(returnObject, GetDictionryObject(fieldInfo, sqlCommand.ExecuteReader()));
                    }
                }
                else if (Attribute.IsDefined(fieldInfo, typeof(ListMapAttribute)))
                {
                    ListMapAttribute listMapAttribute = (ListMapAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(ListMapAttribute));
                    using (DataManager.Current.OpenConnection())
                    {
                        if (!listMapAttribute.IsStoredProcedure)
                        {
                            sqlCommand = DataManager.CreateCommand(listMapAttribute.Command);
                        }
                        else
                        {
                            sqlCommand = DataManager.CreateCommand(listMapAttribute.Command, CommandType.StoredProcedure);
                        }
                        foreach (SqlParameter param in sqlCommand.Parameters)
                        {
                            string fieldName = param.ParameterName.Substring(1);                             //without the "@"
                            param.Value = returnObject.GetType().GetField(fieldName).GetValue(returnObject);
                        }

                        fieldInfo.SetValue(returnObject, GetListObject(fieldInfo, sqlCommand.ExecuteReader()));
                    }
                }
            }

            return((T)returnObject);
        }
        public static IDictionary GetDictionryObject(FieldInfo fieldInfo, IDataReader sqlDataReader)
        {
            Type keyElement  = null;
            Type typeElement = null;

            //Check that it is realy dictionary
            string dictionaryKey = string.Empty;

            if (!fieldInfo.FieldType.IsGenericType || fieldInfo.FieldType.GetGenericTypeDefinition() == typeof(IDictionary))
            {
                throw new Exception("This is not generic Dictionary");
            }

            if (!Attribute.IsDefined(fieldInfo, typeof(DictionaryMapAttribute)))
            {
                throw new Exception("DictionaryMapatrribute not defined");
            }


            //build the dictionary object
            DictionaryMapAttribute dictionaryMapAttribute = (DictionaryMapAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(DictionaryMapAttribute));

            keyElement  = fieldInfo.FieldType.GetGenericArguments()[0];
            typeElement = fieldInfo.FieldType.GetGenericArguments()[1];
            IDictionary returnObject = (IDictionary)Activator.CreateInstance(fieldInfo.FieldType);

            if (typeElement.IsGenericType)
            {
                Type listArgType = typeElement.GetGenericArguments()[0];

                string[] listArgFieldsName = dictionaryMapAttribute.ValueFieldsName.Split(',');
                IList    list;

                while (sqlDataReader.Read())
                {
                    object listArg = Activator.CreateInstance(listArgType);
                    if (!returnObject.Contains(sqlDataReader[dictionaryMapAttribute.KeyName]))
                    {
                        returnObject.Add(sqlDataReader[dictionaryMapAttribute.KeyName], (IList)Activator.CreateInstance(typeElement));
                    }
                    list = (IList)returnObject[sqlDataReader[dictionaryMapAttribute.KeyName]];
                    foreach (string fieldName in listArgFieldsName)
                    {
                        listArgType.GetField(fieldName).SetValue(listArg, sqlDataReader[fieldName]);
                    }
                    list.Add(listArg);
                }
            }
            else
            {
                while (sqlDataReader.Read())
                {
                    object val;
                    if (typeElement != typeof(string))
                    {
                        val = Activator.CreateInstance(typeElement);
                    }
                    else
                    {
                        val = sqlDataReader[dictionaryMapAttribute.ValueFieldsName].ToString();
                    }
                    if (!returnObject.Contains(sqlDataReader[dictionaryMapAttribute.KeyName]))
                    {
                        returnObject.Add(sqlDataReader[dictionaryMapAttribute.KeyName], val);
                    }
                }
            }
            sqlDataReader.Dispose();
            return(returnObject);
        }