Issues

Ditto - The Friendly Poco Mapper for Umbraco

If all goes well and I’ve managed to convince the editorial staff that it’s a great idea there should be a picture above this article of me dressed as my namesake in Team Rocket (you’ll understand this in a minute) but with a kilt and a beard looking all awesome.

I’ve promised them a kick-ass article in exchange so here goes…

I’m going to write today about a little package myself and notable others have been working on called Ditto. You’ve most likely already heard some of the chatter about it on Twitter but I’d like to go into some detail about what it does and how it can make your life working with Umbraco super sweet.

メタモン (Metamon - The Japanese name for Ditto)

One of the most attractive features of Umbraco to developers and publishers is its flexibility. If you can dream it up, Umbraco can display it. Almost any data type imaginable can be constructed for display in the back office. That’s amazing and it’s one of the many reasons why thousands of developers are installing the CMS every year and why I enjoy using it. That power and flexibility though, has, in my opinion, always come with a price - The native Umbraco API doesn’t supply strongly types models for your MVC views.

If you can dream it up, Umbraco can display it.

Strong Typing

Opens dictionary… Strong typing involves the strict enforcement of type rules with no exceptions, allowing the detection of incorrect type usage either at run time or at compile time. Having strong typing catches more type errors than weak typing, resulting in fewer hard errors. It can cut down on many hours of painful debugging.

Umbraco offers what I would call “Stringly Typing”. You can get your property type out of the API but you have to pass a string in order to do so. That’s pretty damn cool but it doesn’t quite feel natural and easy enough for me to use as a developer. I’m lazy and the last thing I want to do it type lots and learn how to spell things.

Other people seem to agree; there are several packages available out in the internets that offer strong typed models within Umbraco.

  • Zbu.ModelsBuilder
  • Umbraco Mapper
  • Glass Mapper - for Umbraco
  • UmbCodeGen
  • Umbraco Inception
  • uSiteBuilder
  • uMapper and it’s fork nuMapper

None of these packages, while they are very clever, offered the simplicity that I required when looking at possible solutions. One of the many things I feel strongly about when looking at an API is ease of use and as soon as I saw Ditto I knew I was on to a winner.

A Little History

Ditto was originally written by those two titans of the Umbraco community Lee Kelleher and Matt Brailsford after reading a rather clever little article by Darren Ferguson.

After I found it, I couldn’t help myself but start to tinker around with it, rewriting a lot of the functionality to improve performance and flexibility, the guys were most welcoming of my input and added me to the team for my efforts. We’ve had great help also from Jeavon Leopold and Hendy Racher who’ve contributed great code and ideas to the package. We’re now working hard to deliver something a wee bit special.

In case you were wondering, the name and logo are shamelessly stolen from Pokémon. (My nonsense earlier on should be more clear now)

The Friendly POCO Mapper

Ditto really is friendly; the API really couldn’t be more simple, providing two main methods to tap into.

IPublishedContent.As<T>();
RenderModel.As<T>();

They do exactly what they say on the tin. The first converts the instance of IPublishedContent to the given type and the second converts the Content property of the RenderModel to the given type. These methods will accept any POCO (Plain Old CLR Object) or a class that like the built-in PublishedContentModel that implements IPublishedContent.

There’s also a separate package that implements the IPublishedContentModelFactory interface that ships with Umbraco 7. (More on that later).

Personally I’m a fan of creating really clean classes to create my models and will use composite document types to define interfaces in the back office. That can take more time to set up for your first project but done correctly you can have neat, reusable classes for every build. It’s up to you if you want to inherit from PublishedContentModel, in my examples I will do, but bear in mind, if you are not using the factory then many of the navigation methods will be of little use to you.

Showtime!

For the purposes of demonstration here’s a standard DocumentType with a few properties: Title, Body Text and Image:

And a corresponding C# class.

public class MyTextPage : PublishedContentModel
{
    public MyTextPage(IPublishedContent content) 
    : base(content) 
    { 
    }

    public string Title { get; set; }

    public HtmlString BodyText { get; set; }

    public Image Image { get; set; }
}

In this class we have a three properties defined: Title, BodyText, and Image. Each of them when queried will represent the property that you have defined when setting up your DocumentType in the back office. You’ll have noticed that we have set the property type of two of those properties to HtmlString and Image without any extra attribution required.

The BodyText property represents a Richtext editor data type. Ditto will automatically map the property to a HtmlString instance and parse any links for you. The Image property represents a Media Picker, this is mapped to another custom C# class as follows.

[TypeConverter(typeof(DittoMediaPickerConverter))]
public class Image : PublishedContentModel
{
    public Image(IPublishedContent content) 
    : base(content) 
    { 
    }

    [UmbracoProperty(Constants.Conventions.Media.Bytes)]
    public int Bytes { get; set; }

    [UmbracoProperty(Constants.Conventions.Media.Extension)]
    public string Extension { get; set; }
}

Note: You could also map the width and height properties using the same approach. I won’t though here so you don’t go code blind.

Type Converters

So there’s a few extra things going on in this class: First thing you’ll spot is a TypeConverter attribute at the top of the class. This tells Ditto what converter to use when creating the property value. There are several built into Ditto available for you.

  • DittoContentPickerConverter
  • DittoConverter (Base class for all converters.)
  • DittoEnumConverter
  • DittoHtmlStringConverter (Runs automatically.)
  • DittoMediaPickerConverter
  • DittoMemberPickerConverter
  • DittoMultipleMediaPickerConverter
  • DittoPickerConverter (Super useful and the best choice for inheriting from. )
  • DittoUltimatePickerConverter (For Umbraco v6)

If you are not familiar with .NET TypeConverters, please read Scott Hanselman’s blog post: TypeConverters: There’s not enough TypeDescripter.GetConverter in the world. This gives a good ‘real-world’ understanding of their purpose.

Then from there, to find out more, refer to the MSDN documentation on How to: Implement a Type Converter

The type converters logic run as follows: If a class is decorated with a TypeConverterAttribute then Ditto will map any reference to that class using the defined converter. If you want to change that behaviour for specific properties you can specify a new attribute declaration on the property on your parent class. Ditto can also handle enumerable properties and will map the correct type parameter when it finds one. It can also tell when you want an enumerable collection or a single item and will return the right thing.

Writing custom type converters is a painless process, especially if you inherit from the ones built into Ditto. Here’s an example one that maps a picker from the awesome nuPickers project.

public class NuPickerPickerConverter : DittoPickerConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string) || sourceType == typeof(Picker))
        {
            return true;
        }

        return base.CanConvertFrom(context, sourceType);
    }


    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        Picker picker = value as Picker;
        if (picker != null)
        {
            return base.ConvertFrom(context, culture, picker.PickedKeys);
        }


        return base.ConvertFrom(context, culture, value);
    }
}

Not bad eh?

Value Resolvers

The second thing you would have spotted would have been the UmbracoPropertyattribute that decorated the two properties.

[UmbracoProperty(Constants.Conventions.Media.Extension)]
public string Extension { get; set; }

This attribute tells something we call a ValueResolver that  gives Ditto additional instructions, since we are deviating from normal behaviour, on how to retrieve the untyped property from Umbraco. In this example the property is stored as umbracoExtension (That Constants class is built into Umbraco btw, dead useful!) so we are telling Ditto to map to a property matching that name.

As with the type converters there are some built in for you to use:

  • DittoValueResolver (Base class all resolvers inherit from.)
  • UmbracoDictionaryValueResolver (Grabs values from the dictionary)
  • UmbracoPropertyValueResolver(Maps to different property names and specifies recursion.)

As of writing there is a resolver being written that allows parsing of relations but I don’t know when that will be added to the mix.

Once mapped these properties can be called at will from in your controllers or views as you would in a standard MVC project.

Here is an example of using the As<T> method within your Razor view:

@using Our.Umbraco.Ditto
@inherits UmbracoTemplatePage
@{
    MyTextPage textPage = Model.Content.As<MyTextPage>();
}
<h1>@textPage.Title</h1>
@poco.BodyText
<p>
    <img src="@textPage.Image.Url" alt="@textPage.Image.Name" />
</p>

As you can see, it really doesn’t take much for you to create your strong typed classes. We’ve worked very hard to ensure that it is very developer friendly.

Other Cool Stuff

Ditto Ignore

For situations where you would rather that Ditto did not attempt to map a DocumentType property with one of your POCO models properties, you can use the DittoIgnore attribute:

[DittoIgnore]
public Image Image { get; set; }

Now when you map your content node, the ignored property (in this example, Image) will be set as the default value for that type (in this case it’s null).

The DittoIgnore attribute is useful for when you want to construct more complex POCO models.

DittoPublishedContentModelFactory

As mentioned above (Yeah, I know there’s been a wall of text since then) Ditto offers a package that implements IPublishedContentModelFactory (Umbraco v7.1.4+) which can automate the binding process for you.

The following code demonstrates how to enable that functionality.

using Our.Umbraco.Ditto;




public class ConfigurePublishedContentModelFactory : ApplicationEventHandler
{
    protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
    {
        var types = PluginManager.Current.ResolveTypes<PublishedContentModel>();
        var factory = new DittoPublishedContentModelFactory(types);
        PublishedContentModelFactoryResolver.Current.SetFactory(factory);
    }
}

From there all the properties of your class (including navigation properties) will be automatically mapped to your POCO.

Proxied Classes

This is one of my favourite bit’s of functionality that we’ve built into Ditto and is some of the most complicated code I have ever written. I am super proud of it and you should definitely have a wee look at the source.

A few of you will have been thinking all the while reading this article, “Well that’s all nice James, but what about performance?” and you would have been right in doing so. Converting all the properties does not come for free. However the code linked above (on top of some other super clever performance optimisation code) makes Ditto super snappy when used correctly.

If you’ve ever used Code First with Entity Framework you’ll know that they have the functionality to lazily load properties by marking the properties as virtual. I’ve always been a big fan of that functionality and now you can do the same with Ditto. (Oh freaking yeah!)

Whenever a property is found in a POCO class that is marked virtual Ditto will switch to lazy loading mode. Instead of your POCO being returned, a new proxy class, dynamically generated in memory that inherits your class is returned instead. At runtime this is treated as if it was your POCO class but internally the dynamic proxy class has overridden all your virtually marked properties with versions that are  intercepted and lazily invoked using the Lazy<T> class.

If we had marked the Image property as virtual in our class above the output proxy class generated at runtime would look something like this.

public class MyTextPageProxy : MyTextPage, IProxy
{
    private IInterceptor interceptor;




    public MyTextPageProxy(IPublishedContent content) 
    : base(content) 
    { 
    }




    public override int get_Image()
    {
        IInterceptor interceptor = ((IProxy)this).Interceptor;
        if (interceptor == null)
        {
            throw new NotImplementedException();
        }
        return (Image)interceptor.Intercept(MethodBase.GetMethodFromHandle(typeof(MyTextPage).GetMethod("get_Image").MethodHandle), null);
    }




    public override void set_Image(Image image)
    {
        IInterceptor interceptor = ((IProxy)this).Interceptor;
        if (interceptor == null)
        {
            throw new NotImplementedException();
        }
        interceptor.Intercept(MethodBase.GetMethodFromHandle(typeof(MyTextPage).GetMethod("set_Image", new Type[] { typeof(Image) }).MethodHandle), image);
    }




    public virtual IInterceptor Our.Umbraco.Ditto.IProxy.Interceptor
    {
        get
        {
            return this.interceptor;
        }
        set
        {   
            this.interceptor = value;
        }
    }
}

If that isn’t the coolest thing you’ve seen code-wise in a while I envy you and want to see what you’ve been working on.

You don’t have to worry about that complexity at all with Ditto

It all happens under the hood and makes a huge difference to your output when parsing collections (Think a news section or main menu).

I Think I’ve Waffled on Enough Now

All in all there’s a hell of a lot of really useful and clever functionality built into Ditto to make your life working with Umbraco even more kick-ass than it is already. I’ve been dogfooding it constantly during the development process and I’m really pleased with the quality and performance of the output of the websites I’ve produced. I heartily recommend you give it a go. (Not biased at all!)

Ditto is available on Nuget with bleeding edge builds on Myget. You can also install it from Our Umbraco where we have a forum for helping out should you ever get stuck.

So download it, install it, and forever surf into work on a wave of awesome, happy in the knowledge that your working day shall be a slice of gold!

We should have called it Awesomo…

Adiós Amigos!

comments powered by Disqus