Thursday, August 07, 2008
 
   
 
Welcome to my site

First let me say thanks for stopping by my site. My name is David Hanson-Graville and I am a IT consultant working in the UK. Let me make it clear, I am passionate about technology and specifically .net and its various forms. I've programmed in a range of langages, but I can say, I am now at my happiest when coding with c#. I hope my blog is an enjoyable & educational read and please feel free to email me at David.Hanson@OnTheBlog.net if you have any questions. 

Search Minimize
Print  
Archive Minimize
Print  
Dipstick Survey Minimize
What technology are you most excited about?











Submit Survey  View Results
Print  
Contact me Minimize
Print  
Silverlight News Minimize
silverlight - Google News
Print  
LINQ to Reflection Part 2: Reading Fields Minimize
Location: BlogsOnTheBlog    
Posted by: David Hanson Fri, 25 Apr 2008 11:34:23 GMT
In part 1 of my LINQ to Reflection series I outlined some of the key drivers behind me creating a set of extension methods that can be used to query any CLR type. I also outlined that I am looking to extend this further with support for reading/writing of data, mocking, invocation, interception and other useful behaviours.  This post is purely focused on the reading of field data using the LINQ to Reflection extension methods.  
 
Before we get into the details of how we query data, we first need to create some tests data that will be used for each sample. Below is a method that is used to build object graph that is comprised simple and complex types with multiple child objects.  Note: We are already starting to use our LINQ to Reflection methods in order to create tests data.
 
        ///<summary>
        /// Sets up an object graph for our different test scenarios.
        ///</summary>
        public static Person GetTestData()
        {
            Person person = new Person();
            return FillPerson(person,3, 4);
        }
 
        ///<summary>
        /// Fills the person with test data.
        ///</summary>
        ///<param name="person">The person.</param>
        ///<param name="levelsDeep">The levels deep we wish to populate.</param>
        ///<returns>A person instance</returns>
        private static Person FillPerson(Person person,int noOfChildren, int levelsDeep)
        {
            //Update our name.
            person
                .Field<string>("_firstName").Update("Joe")
                .Field<string>("_lastName").Update("Blog " + levelsDeep.ToString());
                    
            //Add a Partner
            Person partner = new Person();
            partner.Partner = person;
            person.Partner = partner;
 
            //We have reached or level.
            if (levelsDeep == 0)
                return person;
            else
            {
                //Lets create the children for this person.
                for (int i = 0; i < noOfChildren; i++)
                {
                    Person child = new Person();
                    //Add children.
                    person.Children.Add(FillPerson(child, 4, levelsDeep - 1));
                }
            }
 
            return person;
        }
 
The result of this method is a person being created with children, grandchildren, great grandchildren and great great grandchildren. Each generation will have a lower number appended to their name. Therefore a 4 equates to the oldest and 0 equates to the youngest. This is shown in the locals window below.
 
 
Now that we have some tests data to work with it’s about time we starting looking at some LINQ to Reflection samples. As mentioned in part 1, LINQ to Reflection provides extension methods for the Object type. This therefore means, if you import the LINQ.Reflection namespace, every single CLR type in scope is queryable. This includes base types such as string, int, decimal, object & any other type. Below is a an example of the intellisense being displayed on a string class once the LINQ.Reflection namespace has been imported.
 
 
Having the extension methods available on all .net types & at any point is one of the features I consider the most compelling. You will also notices that the extension methods use .NET generics, this is vitally important as I felt type safety and intellisense support is invaluable when you are digging many levels deep into an object graph.  I am hoping as we start to delve deeper you start to see the benefits of these decisions.  
 
Sample 1 – Reading Fields from an instance.
 
string firstName = person.Field<string>("_firstName").Value;
DateTime DOB = person.Field<DateTime>("_dateOfBirth").Value;
Console.WriteLine("First Name: {0} - Year Born: {1}", firstName, DOB.Year);
 
This example shows how we can read fields held on an instanced type [Person]. FYI these fields are private. LINQ to Reflection allows you to read fields on any type whether private, protected, internal & public. In order to read a field we use the Field<T> extension method.  We pass the type argument to the Field method in order to strongly type the value we are going to be accessing person.Field<DateTime>. Next we need to pass the name of the field we are trying to access, we do this using the name parameter ("_dateOfBirth").The final part is to call the Value property which will return a strongly typed value from the field. The result of running this code is shown below.
 
First Name: Joe - Year Born: 1978
 
Sample 2 – Reading complex fields from an instance.
 
In the previous example we are accessing fields on our person instance using fairly simple types. However, the Field<T> method allows us to use generics therefore we can pass any type we desire into the type argument. Often fields that sit within an object are complex in nature, they maybe other entities, collections or connections etc. This example shows the Field<T> method being called in order to return a strongly typed collection of persons .Field<List<Person>>.  We then iterate around this collection writing out each person’s name and age.
 
List<Person> children = person.Field<List<Person>>("_children").Value;
 
foreach(Person child in children)
     Console.WriteLine("First Name: {0} - Year Born: {1}", person.Name, person.Age);
 
The output from this code is shown below.
 
First Name: Joe Blog 4 - Age: 29
First Name: Joe Blog 4 - Age: 29
First Name: Joe Blog 4 - Age: 29
 
Sample 3 – Reading a field where the type is inaccessibly.
 
At this point you may be wondering what you do in the situation whereby you do not know the type of the field. In these situations you can down cast the field to its lowest common denominator for example a custom collection could be converted to a List<T> or an entity could be downcast to an object. Below is an example of accessing a field that you do not know the type of.
 
person.Field<Object>("_dateOfBirth").Value;
 
 
Sample 4 – Obtaining a list of available fields.
 
During testing of your own objects you often know what internal fields are being used. Therefore obtaining the name is not an issue. However, some types you wont and therefore you need a way to interrogate the object in order to determine the field name. The Fields extension method provides this functionality.  It returns a collection of Linq.Reflection.Field objects which can be used to read values or alternatively drill down deeper. Below is an example of reading all fields on the string class.
 
foreach (Field<object> field in "hello" Fields())
    Console.WriteLine("Field Name: {0}", field.Name);
 
And the result of running this code is shown below.
 
Field Name: m_arrayLength
Field Name: m_stringLength
Field Name: m_firstChar
Field Name: Empty
Field Name: WhitespaceChars
Field Name: TrimHead
Field Name: TrimTail
Field Name: TrimBoth
Field Name: charPtrAlignConst
Field Name: alignConst
 
Sample 5 – Finding a field with LINQ to Reflection and LINQ to Objects.
 
This example shows how we can use our LINQ to reflection extension methods to obtain a list of Fields and then perform a LINQ query on our collection in order to find a specific field.
 
IEnumerable<Field<Object>> fields = "Hello"
                                        .Fields()
                                        .Where(field => field.Name == "alignConst");
 
foreach (Field<Object> f in fields)
    Console.WriteLine(f.Name);
 
The output from this code is shown below.
 
alignConst
 
 
Sample 6 – Reading fields from deep inside our object graph.
 
Now that you have seen how we can access fields on our top level object we will now look at how we can drill down into our object graph. As the Field<T> extension method returns a representation of a Field and that we can access the value of that field using the Value property, we can continue to dig deeper. Below is an example that well drill down each of the children collections that hangs of a person until we read the bottom.
 
Person greatGreatGrandson = person
                            .Field<List<Person>>("_children").Value[0]
                                .Field<List<Person>>("_children").Value[0]
                                    .Field<List<Person>>("_children").Value[0]
                                        .Field<List<Person>>("_children").Value[0];
 
Console.WriteLine("Great great grandson : {0}", greatGreatGrandson.Name);
 
The chaining of Field<T> methods allows us to step down the tree each step returning a strongly typed person collection. You can see this as we access the indexer on the collection. [0].. If we run this code we get the following result. The “Joe Blog 0” represents the last generation in our tree. Note... if we were to chain another Field method we would hit a null reference exception.
 
Great great grandson : Joe Blog 0
 
 
So that completes Part 2 of this blog series. From this you should be able to grasp the way that field data can be read from any type of object. Further, you can see how the power of chaining allows us to writing code that represents visually what we are trying to attain. You will see this pattern repeated later on when we look at property data, method and constants. In Part 3 however we will look at how we can perform updates on data by extending these samples.
 
  
Permalink |  Trackback

Comments (1)   Add Comment
LINQ to Reflection Part 3: Updating Fields    By TrackBack on Mon, 28 Apr 2008 13:30:07 GMT
In part 2 of this LINQ 2 Reflection series I took you through how we go about querying fields that may existing within an object graph. Before we proceed, it’s important to remember that a call to obj ...
# The Thinker


Your name:
Title:
Comment:
Security Code
Enter the code shown above in the box below
Add Comment   Cancel