Thursday, January 27, 2011

Be happy with dynamic objects in Sitecore 6.4

Dynamic objects, a feature in .NET 4.0 is supposed to bring great possibilities. 
Thomas Eldblom and Jens Mikkelsen asked the question earlier: "
Will dynamics in .NET 4 change the way we do Sitecore?"
Personally I believe you should use dynamic objects with care, f.e. for XML, wrapping ActiveX/COM and stuff like that (as seen here). 
Is handling the access to Sitecore item fields, or rendering of Sitecore item content, an example of good usage of Dynamic Objects?

To find out, I first created a simple test class, called DynamicItem. This dynamic class only handles Field of an Item, to keep it simple. It returns the string that the FieldRenderer creates for the field requested. Basically it's a dynamic wrapper for a Sitecore item.
This is the class I created:
public class DynamicItem : DynamicObject
   {  
      Item mItem;

      public static implicit operator DynamicItem(Item pItem)
      {
         if (pItem != null)
            return new DynamicItem(pItem);
         return null;
      }

      public DynamicItem(Item pItem)
      {
         mItem = pItem;
      }

      public override bool TryGetMember(GetMemberBinder binder, out object result)
      {
         Field lField = mItem.Fields[binder.Name];
         if (lField != null)
         {
            result = FieldRenderer.Render(mItem, binder.Name);
         }
         else
         {
            result = null;
            Exception lException =new Exception(String.Format("Item {0}, of template {1}, which hasn't a {2} field.", mItem.Paths.ContentPath, mItem.TemplateName, binder.Name));
            throw lException;
         }
         return lField != null;
      }
   }
 
With this class in place, what can we do in a UserControl or SubLayout?
In the codebehind of an existing SubLayout, I added a simple property:

        public dynamic DynamicItem
        {
           get
           {
              return (IQuality.Common.Sitecore.DynamicItem)Sitecore.Context.Item;
           }
        }


This makes a front end developer -friendly syntax possible, see the following examples:
<%# DynamicItem.Title%> 
<%# DynamicItem.Body%>
<%# DynamicItem.Image%>  

I guess it's clear what the sample does: it renders the same output as the following:
<sc:FieldRenderer ID="frTitle" FieldName="Title" runat="server"/>
<sc:FieldRenderer ID="frBody"  FieldName="Body" runat="server"/>
<sc:FieldRenderer ID="frImage"  FieldName="Image" runat="server"/>

 Before a front end developer will be truly happy, we'd need to do some work on the image (handling the parameters, f.e.) but it shows potential!

Why is this a good idea?
I think it's good, because disadvantages like the absence of compile time checking and the lack of intellisense support do not apply(since these apply to fieldrenderers and the retrieval of field values of items as well.

Would this be a nice shared source module, or an addition to an existing one?
Tell me!





3 comments:

  1. Because dynamic internally uses reflection-like mechanics, it's slower than just getting a dictionary key. Solutions that actually generate strongly typed objects (i.e. the Custom Item Generator on shared source, and I have one I use that hasn't been publically released yet) can be made just as fast as item access while also gaining IntelliSense and compile time checking.

    ReplyDelete
  2. @Kamsar: Dynamic objects supposedly are somewhat slower, but not as slow as regular reflection. You can read about this here: http://code.logos.com/blog/2010/03/the_visitor_pattern_and_dynamic_in_c_4.html and here: http://www.buunguyen.net/blog/fasterflect-vs-c-4-0-dynamic.html.

    ReplyDelete
  3. I have started to look at the same thing for the Glass.Sitecore.Mapper framework and would appreciate any input you could give, http://www.glass.lu/?p=407.

    ReplyDelete