Click here to Skip to main content
15,896,453 members
Articles / Programming Languages / C#

Single Object Property Database

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
30 Oct 20073 min read 24.8K   14  
Object Properties Snapshot Management
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace PropertyMapping
{
    /// <summary>
    /// The dictionary construct for mantaining and managing object registrtion
    /// as well it's properties  Get/Set .  
    /// </summary>
    /// 
      
    internal sealed class MapDictionary : Dictionary<string,List<string>>
    {
        PropertyValuesTable propertyValuesTable = new PropertyValuesTable();

        /// <summary>
        /// Add for regitering property of the object 
        /// </summary>
        /// <param name="key">The key is object type identifier</param>
        /// <param name="propName">The name of the property to register</param>
        internal  void AddProperty(string key,string propName)
        {
            if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(propName))
                throw new ArgumentNullException();     
       
            List<string> propList = null; 
            if(!TryGetValue(key,out propList)) 
            {
                propList = new List<string>();
                Add(key, propList);
            }
      
            propList.Add(propName);
      
        }

     

      

        /// <summary>
        /// Saving the snapshot of the object registerd properties 
        /// </summary>
        /// <param name="objToSave">Object to properties to save to</param>
        /// <param name="uniqueKey">The snapshot unique identifier</param>
        internal void SaveObjectSnapshot(object objToSave, string uniqueKey,List<string>propertyNames,bool ignoreStandardValue)
        {
            if(objToSave == null)
                throw new ArgumentNullException("objToSave");

            Type objType = objToSave.GetType();
            string typeDefString = UniqueKeyFromObjectType(objType);

            if (objType == null)
                throw new ArgumentNullException("Can not get object type information.");

            if (propertyValuesTable.ContainsKey(uniqueKey))
                throw new ArgumentException("The key is not unique.");

            if (!ContainsKey(typeDefString))
                throw new ArgumentException("Object not registered yet.");

            List<string> propNames = this[typeDefString];
            if (propNames == null || propNames.Count == 0)
                throw new ObjectHasNotValidProperties(objToSave);


            for (int i = 0; i < propNames.Count; i++)
            {
                string pName = propNames[i];

                // control on property names collection if exists
                if (propertyNames != null && propertyNames.Count > 0)
                {
                    if (!propertyNames.Contains(pName)) continue;
                }               

                PropertyInfo pi = objType.GetProperty(pName);                
                object objValue = GetValueFromProperty(objToSave, pi);
                // control on StandardValue attribute if exists
                if (!ignoreStandardValue)
                {
                    object[] attrCol = pi.GetCustomAttributes(typeof(MapPropertyAttribute), false);
                    if (attrCol == null || attrCol.Length == 0)
                        continue;

                    MapPropertyAttribute mpAt = attrCol[0] as MapPropertyAttribute;
                    if (mpAt == null) continue;
                    if (mpAt.StandardValue == null) continue;

                    if (objValue.Equals(mpAt.StandardValue)) continue; 
                    

                }

                
                propertyValuesTable.AddPropertyValue(uniqueKey, pName, objValue);
            }

           

        }

        /// <summary>
        /// Geting value from property , if the property return value 
        /// is reference type try to clone it 
        /// </summary>
        /// <param name="obj">Object to get the property</param>
        /// <param name="pi"> PropertyInfo object to examine</param>
        /// <returns></returns>
        object GetValueFromProperty(object obj,PropertyInfo pi)
        {
            
            object o = pi.GetValue(obj, null);
            if (pi.PropertyType.IsAssignableFrom(typeof(ICloneable)))
                o = (o as ICloneable).Clone();


            return o;
        }

        /// <summary>
        /// Geting the object properties snapshot from the internal database
        /// and asign all requested property values to the object properties
        /// </summary>
        /// <param name="objToFill">Object to fill with snapshot data</param>
        /// <param name="uniqueKey">The unique key of the snapshot to get</param>
        internal void GetObjectSnapshot(object objToFill, string uniqueKey)
        {
            if (objToFill == null)
                throw new ArgumentNullException("objToFill");

            Type objType = objToFill.GetType();
            string typeDefString = UniqueKeyFromObjectType(objType);

            if (objType == null)
                throw new ArgumentNullException("Can not get object type information.");

           
            if (!propertyValuesTable.ContainsKey(uniqueKey))
                throw new ArgumentException("The does not exist.");

            if (!ContainsKey(typeDefString))
                throw new ArgumentException("Object not registered yet.");
            
            NameValueList  propertyValues = propertyValuesTable[uniqueKey];
            if (propertyValues == null || propertyValues.Count == 0)
                throw new ObjectHasNotValidProperties(objToFill);   

        
            foreach(NameValue  nv in propertyValues)
            {
                string pName = nv.Name;
                PropertyInfo pi = objType.GetProperty(pName);
                pi.SetValue(objToFill, nv.Value , null);                
            }

        }

        /// <summary>
        /// Get unique key from object
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        internal static string UniqueKeyFromObject(object obj)
        {
            if (obj == null) return null;

            return obj.GetType().ToString();
        }

        /// <summary>
        /// Get unique key from object type
        /// </summary>
        /// <param name="objType"></param>
        /// <returns></returns>
        internal static string UniqueKeyFromObjectType(Type objType)
        {
            if (objType == null) return null;

            return objType.ToString();
        }


        /// <summary>
        /// Fill the object property values with the requested snapshot data. 
        /// </summary>
        /// <param name="objToExamine"></param>
        /// <param name="uniqueKey"></param>
        internal void FillObjectProperties(object objToExamine, string uniqueKey)
        {
            if (objToExamine == null)
                throw new ArgumentNullException("objToExamine.");
            if( string.IsNullOrEmpty(uniqueKey))
                throw new ArgumentNullException("uniqueKey.");
            
            GetObjectSnapshot(objToExamine, uniqueKey);
        }

        /// <summary>
        /// Save object snapshot in the internal database
        /// </summary>
        /// <param name="objToExamine">Object properties need to save</param>
        /// <param name="uniqueKey">The unique key to associate to the saved snapshot</param>
        internal  void  SaveObjectMappedProperties(object objToExamine, string uniqueKey)
        {
            if (objToExamine == null)
                throw new ArgumentException("objToExamine.");
            if (string.IsNullOrEmpty(uniqueKey))
                throw new ArgumentException("uniqueKey.");

            SaveObjectSnapshot(objToExamine, uniqueKey,null,true);
        }


        /// <summary>
        /// Save object snapshot in the internal database
        /// </summary>
        /// <param name="objToExamine">Object properties need to save</param>
        /// <param name="ignorePropertyStandardValue">If false only the property with the value different from 
        /// the StandardValue of the MapPropertyAttribute will be saved </param>
        internal void SaveObjectMappedProperties(object objToExamine, string uniqueKey, bool ignorePropertyStandardValue)
        {
            if (objToExamine == null || uniqueKey == null)
                throw new ArgumentException("Null arguments.");
            if (uniqueKey == string.Empty)
                throw new ArgumentException("The unique key can not be empty.");

            SaveObjectSnapshot(objToExamine, uniqueKey, null, ignorePropertyStandardValue);
        }


        /// <summary>
        /// Save object snapshot in the internal database
        /// </summary>
        /// <param name="objToExamine">Object properties need to save</param>
        /// <param name="uniqueKey">The unique key to associate to the saved snapshot</param>
        /// <param name="propertyNames">The list of the properties to save in</param>
        internal void SaveObjectMappedProperties(object objToExamine, string uniqueKey,List<string> propertyNames)
        {
            if (objToExamine == null || uniqueKey == null)
                throw new ArgumentException("Null arguments.");
            if (uniqueKey == string.Empty)
                throw new ArgumentException("The unique key can not be empty.");

            SaveObjectSnapshot(objToExamine, uniqueKey,propertyNames,true);
        }


        internal List<string> UniqueKeys
        {
            get
            {
                return propertyValuesTable.UniqueKeys;
            }
        }

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions