Dynamic Objects in VB 2010

Introduction

Riddle: When is an object not an object? When it is a dynamic object. Well, not really. Dynamic objects are a mechanism for mapping class-like object behavior and binding at runtime. The short of it is that you have something you want to treat like an instance of a pre-defined class without having the pre-defined class, just the data.

The first scenario that comes to mind is legacy type data. Suppose you have some text data representing legacy data. Further suppose that the text data contains name and value pairs. In the past you would have to sift through the data, map a custom class to the names, and then parse the data populating the custom objects. Well, dynamic objects sort of let you define the mapping scenario without necessarily defining the custom class. Instead you define a child class that inherits from System.Dynamic.DynamicObject and write code that describes how to make sense of the data. Then, you treat instances of the dynamic objects as if they were the instances of the (non-existent) custom class using member of (.) syntax.

The underlying data can be something is simple as a string, a text file, or an XML file. The result is that your write code like object.member and the DynamicObject plumbing binds the member name dynamically (or, at runtime, if you will).

Defining a Simple DynamicObject

To define a DynamicObject in VB define a new class that inherits from System.Dynamic.DynamicObject. Override one of the many available members based on how or what you want to invoke at runtime. For instance override TryGetMember to get member properties. TryGetMember accepts a GetMemberBinder parameter, a ByRef result that represents the return data, and returns a Boolean indicating success or failure. Listing 1 contains a DynamicObject, SimpleObject that overrides TryGetMember and looks for GetBinderMember.Name values of Name, Street, City_State.

Public Class SimpleObject
    Inherits DynamicObject

    Property Data As String()

    Public Sub New(ByVal Data() As String)
      Me.Data = Data
    End Sub

    Public Overrides Function TryGetMember(ByVal binder As GetMemberBinder,
                                       ByRef result As Object) As Boolean

      Dim item = (From one In Data
                 Where one.Contains(binder.Name)
                 Select one).First()
      
      If binder.Name = "Name" Then
          result = item.Replace("Name: ", "")
          Return True
      ElseIf binder.Name = "Street" Then
          result = item.Replace("Street: ", "")
          Return True
      ElseIf binder.Name = "City_State" Then
          result = item.Replace("City_State: ", "")
          Return True
      End If
      Return False
    End Function
End Class

Listing 1: SimpleObject is a DynamicObject that looks for simple string field values

SimpleObject is initialized with an array of strings containing Name, Street, and City_State data. When an instance of SimpleObject accesses a field at runtime, like SimpleObject.Name, TryGetMember will parse, find the correct string and parse out the "Name: " part returning the data part.

Using a DynamicObject in VB

To use SimpleObject think of it as any other kind of instance of a class. Initialize it with the correct parameters and invoke members as if they were early bound members. The DynamicObject plumbing will resolve the member access.

Listing 2 contains all of the code for the sample. The Module demonstrates how to use SimpleObject.

In the Listing there are two arrays of strings that we want to treat like objects. The Main function initializes two instances of SimpleObject, one for each array of strings. All that is left to do is access the data using member-of (.) syntax. For example, the SimpleObject paul can access Name, Street, and City_State using the same syntax as if there were properties with these names.

Imports System.Dynamic

Public Class SimpleObject
    Inherits DynamicObject

    Property Data As String()

    Public Sub New(ByVal Data() As String)
      Me.Data = Data
    End Sub

    Public Overrides Function TryGetMember(ByVal binder As GetMemberBinder,
                                       ByRef result As Object) As Boolean

      Dim item = (From one In Data
                 Where one.Contains(binder.Name)
                 Select one).First()
      
      If binder.Name = "Name" Then
          result = item.Replace("Name: ", "")
          Return True
      ElseIf binder.Name = "Street" Then
          result = item.Replace("Street: ", "")
          Return True
      ElseIf binder.Name = "City_State" Then
          result = item.Replace("City_State: ", "")
          Return True
      End If
      Return False
    End Function
End Class

Module Module1
    Dim data() As String =
      {"Name: Paul Kimmel",
       "Street: 1313 Mockingbord Ln.",
       "City_State: Flostinspace. MI 55555"}

    Dim data2() As String =
      {"Name: Joe Kunk",
       "Street: 1313 Stargazer Way",
       "City_State: Flostinspace. MI 55555"
       }


    Sub Main()
        Dim paul As Object = New SimpleObject(data)
        Console.WriteLine(paul.Name)
        Console.WriteLine(paul.Street)
        Console.WriteLine(paul.City_State)

        Dim joe As Object = New SimpleObject(data2)
        Console.WriteLine(joe.Name)
        Console.WriteLine(joe.Street)
        Console.WriteLine(joe.City_State)
        Console.ReadLine()
    End Sub
End Module

Listing 2: Initialize SimpleObject with an array of strings but treat it (in this case) as if it had pre-defined Name, Street, and City_State properties.

Summary

Historically when programmers encountered legacy data, strings or XML some kind of code had to be written to parse and populate that data into custom objects. You can still do that of course. You also have the option to use LINQ to XML and a project-select clause-to access the data or you can use DynamicObjects in VS2010.

A DynamicObject uses late binding to let you treat data elements as fully qualified members of a class. There is no mapped class just mapping behaviors if you will. It will be interesting to see how DynamicObjects and late binding make their way into the lexicon of programming techniques.



About the Author

Paul Kimmel

Paul Kimmel is the VB Today columnist for CodeGuru and has written several books on object-oriented programming and .NET. Check out his upcoming book Professional DevExpress ASP.NET Controls (from Wiley) now available on Amazon.com and fine bookstores everywhere. Look for his upcoming book Teach Yourself the ADO.NET Entity Framework in 24 Hours (from Sams). You may contact him for technology questions at pkimmel@softconcepts .com. Paul Kimmel is a Technical Evangelist for Developer Express, Inc, and you can ask him about Developer Express at paulk@devexpress.com and read his DX blog at http:// community.devexpress.com/blogs/paulk.

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • It's hardly surprising that half of small businesses fail within the first 1-5 years. It's not easy to launch a new product, single-handedly manage everything from IT to accounting, fend off the competition, and grow a customer base – all at the same time – even with a great concept. Offering awesome customer service can make the difference between a startup that flies and a startup that dies. Read this white paper to learn nine ways customer support can help you beat the competition and grow your …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds