Random Musings

June 21, 2009

Using reflection to iterate over all the properties inside an object

Filed under: Dynamics CRM — haditeo @ 6:04 pm
Tags: ,

Here are the code snippet before it’s refactored using reflection :

        public DynamicEntity Convert(Project newProject)
        {
            try
            {
                DynamicEntity deProject = new DynamicEntity();
                deProject.Name = "new_project";


                if (newProject.IsProjectRefExist())
                    deProject.Properties.Add(newProject.ProjectRef);

                if (newProject.IsClientExist())
                    deProject.Properties.Add(newProject.Client);

                if (newProject.IsPrimaryContactExist())
                    deProject.Properties.Add(newProject.PrimaryContact);

                if (newProject.IsClientCategoryExist())
                    deProject.Properties.Add(newProject.ClientCategory);

                if (newProject.IsProjectTitleExist())
                    deProject.Properties.Add(newProject.ProjectTitle);

                if (newProject.IsProjectTitleInChineseExist())
                    deProject.Properties.Add(newProject.ProjectTitleInChinese);

                if (newProject.IsAccountManagerExist())
                    deProject.Properties.Add(newProject.AccountManager);

                if (newProject.IsKbaExist())
                    deProject.Properties.Add(newProject.Kba);

                if (newProject.IsServiceTypeExist())
                    deProject.Properties.Add(newProject.ServiceType);

                if (newProject.IsDevelopmentTypeExist())
                    deProject.Properties.Add(newProject.DevelopmentType);

                if (newProject.IsRegionExist())
                    deProject.Properties.Add(newProject.Region);

                if (newProject.IsLocationExist())
                    deProject.Properties.Add(newProject.Location);

                if (newProject.IsCountryExist())
                    deProject.Properties.Add(newProject.Country);

                if (newProject.IsDescriptionExist())
                    deProject.Properties.Add(newProject.Description);

                if (newProject.IsSourceExist())
                    deProject.Properties.Add(newProject.Source);

                if (newProject.IsEstimatedProjectCostExist())
                    deProject.Properties.Add(newProject.EstimatedProjectCost);

                if (newProject.IsEstimatedProjectFeesExist())
                    deProject.Properties.Add(newProject.EstimatedProjectFees);

                if (newProject.IsEstimatedFeesPercentageExist())
                    deProject.Properties.Add(newProject.EstimatedFeesPercentage);

                if (newProject.IsEstimatedProjectStartDateExist())
                    deProject.Properties.Add(newProject.EstimatedProjectStartDate);

                if (newProject.IsEstimatedProjectEndDateExist())
                    deProject.Properties.Add(newProject.EstimatedProjectEndDate);

                return deProject;
            }
            catch (System.Web.Services.Protocols.SoapException ex)
            {
                throw ex;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

and here are the code after it’s refactored

        public DynamicEntity Convert(Project newProject)
        {
            try
            {
                DynamicEntity deProject = new DynamicEntity();
                deProject.Name = "new_project";

                foreach (PropertyInfo projectProperty in typeof(Project).GetProperties())
                {
                    // skip if the method is not exist
                    if ((typeof(Project).GetMethod("Is" + projectProperty.Name + "Exist")) == null)
                        continue;

                    bool isPropertyHasValue = (bool)(typeof(Project).GetMethod("Is" + projectProperty.Name + "Exist")).Invoke(newProject, null);

                    //don't add to the Project's dynamic entity with the null value of the current Project property
                    if (!isPropertyHasValue)
                        continue;

                    deProject.Properties.Add((Property)projectProperty.GetValue(newProject, null));
                }

                return deProject;
            }
            catch (System.Web.Services.Protocols.SoapException ex)
            {
                throw ex;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

Reflection is cool. What reflection techniques that i am using it here ?

  • I am using these code snippet to iterate to all the properties inside an object. The advantage of this is i do not need to hard code additional lines when my business object gets added with additional attributes
    foreach(PropertyInfo projectProperty in typeof(Project).GetProperties())
    {}
    
  • I am using the GetMethod() to check whether a particular method name is indeed exist inside the object
    if ((typeof(Project).GetMethod("Is" + projectProperty.Name + "Exist")) == null)
    
  • I am using the Invoke() to invoke the particular method. Fortunately i do not need to pass the parameter
    (bool)(typeof(Project).GetMethod("Is" + projectProperty.Name + "Exist")).Invoke(newProject, null);
    
  • As usual, i always use the GetValue method to obtain the current property value for the particular object

    (Property)projectProperty.GetValue(newProject, null)
    
Advertisements

3 Comments »

  1. Hello,

    Do you have any experience with setting CrmDateTime values using reflection?

    …I receive the following error “startIndex cannot be larger than length of string.” when trying to set a CrmDateTime field using reflection. Here is a snippet of code:

    // assume crmContact variable is loaded

    // get current datetime value
    Type t = crmContact.GetType();
    CrmDateTime crmDateTime = (CrmDateTime)t.GetProperty(“mydatefield”).GetValue(crmContact, null);
    t.GetProperty(crmField).SetValue(crmContact, dbCrmDateTime, null);

    // prepare datetime from a database
    DateTime dbDateTime = new DateTime(“2010”, “04”, “01”);
    CrmDateTime dbCrmDateTime = new CrmDateTime();
    dbCrmDateTime.date = dbDateTime.ToShortDateString();

    // set datetime using reflection
    t.GetProperty(“mydatefield”).SetValue(crmContact, dbCrmDateTime, null);

    The code fails on the last line with the above error. Any ideas?

    Comment by gcanivet — April 1, 2010 @ 11:55 pm | Reply

    • Actually, poor debugging, the error was due to another issue. The SetValue is no longer causing an error, but it is not updating the datetime. The field becomes null. Here is some simplified code:

      DateTime dbDateTime = DateTime.ParseExact(dbVal, “MMM d yyyy hh:mmtt”, null);
      CrmDateTime dbCrmDateTime = new CrmDateTime();
      dbCrmDateTime.date = dbDateTime.ToString(“M/d/yyyy”);
      Type t = crmContact.GetType();
      t.GetProperty(crmField).SetValue(crmContact, dbCrmDateTime, null);

      This updates the crmField with a blank/null value. Any thoughts would be awesome.

      Comment by gcanivet — April 2, 2010 @ 6:42 am | Reply

      • Nevermind. Setting the dbCrmDateTime.date is not enough, you have to set the time and Value properties of the CrmDateTime object. Not really sure why, but that did the trick. This is working now.

        Comment by gcanivet — April 2, 2010 @ 7:08 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: