I have spent the last 10+ years working with Sitecore and I have loved every minute of it - well almost every minute. The only part that I have never liked is the ridiculous amount of time spent writing boilerplate code to pull item data from Sitecore and populating data class objects. It is tedious and an utter waste of time but more importantly it takes away from the time I could have spent adding real value to the solution.
So yes obviously I created a framework to automate this time consuming work and of course equally obviously your first reaction will be to wonder which rock I have been living under for the past 10 years as there are already numerous frameworks available out there. And the short answer is that, no I have not been living under a rock for 10 years and yes I am well aware of all the other frameworks - in fact I have probably used almost all of them to a certain extend at some point.
So why did I decide to create yet another framework? Well first of all I honestly feel that the majority of the existing frameworks are either to overly complex and all-consuming or too simple to add any real value and most importantly none of them really seem to pay much attention to what I believe is the single most important thing and that is data validation.
I have used the Glass.Mapper framework from time to time but I have always felt that it was a bit cumbersome. It requires a lot of configuration, it has a lot of third party dependencies and it tries very hard to abstract away the underlying Sitecore data models such as the Item and Field classes. That is of course a huge benefit if you want to write test driven code but the true matter of the fact is that as developers we all know that most of the Sitecore code we write is extremely simple and only tasked with retrieving information from Sitecore to present in a rendering. This is hardly the prime field of test driven development and in fact in almost any case where the code breaks it is not because of design time errors in the code but runtime errors caused by editors creating the wrong item types in Sitecore or accidentally dragging items into folders where they don’t belong.
Another problem with the frameworks that attempts to remove all ties to the Sitecore data layer is that they are almost in direct conflict with the direction that the current Sitecore evolution is headed in. Especially Sitecore’s added focus on the page editor experience means that exposing the items and fields directly to the UI layer has almost become a necessity. Also we have seen quite a few curve balls from Sitecore’s development team as the platform evolves which takes different areas of the product in surprising directions that requires direct and unhindered access to the Sitecore API. Therefore abstracting the underlying Sitecore API away is simply not a smart or safe move at this time as it may severely restrict some of the functionality that Sitecore offers out of the box and it can make upgrading to future versions difficult or impossible. Not to mention that it seems a bit silly to create a solution based on Sitecore and then spend the majority of your development effort trying to remove all dependencies on Sitecore not to mention then trying to sneak it in through the backdoor to support page editing at the UI level.
So what about the frameworks that actually embrace Sitecore such as the CustomItemGenerator from Velir? Well in my opinion they are a bit simplified and they feel a lot like a “one size fits all” paradigm. Most of them are primarily automated code generation tools and although they will save you time they will also more or less dictate how you should build your data classes and in most cases they don’t really have any functionality for retrieving the item data from Sitecore and instantiating the model classes which means that you still have to write a lot of boiler plate code making the benefits fairly limited.
One thing that all the different frameworks seem to have in common however is the surprising lack of any kind of data validation mechanisms whatsoever. It seems that you can take any old Sitecore item and stick it in a model class without any consideration as to whether the item actually matches the model class and has the fields and information that is needed to drive the model. Now when coupled with my previous comment about editors and their ever surprising ability to use the wrong item types at the wrong place or accidentally dragging items into places where they don’t belong the whole idea of populating a model class without any data validation is indeed a scary though and I dare state that this has probably caused more runtime errors than faulty code ever has.
All of these considerations lead me to conclude that I needed something else and that is why I decided to create yet another framework even though I haven’t been living under a rock for 10 years.
So what were my requirements? Well first of all it had to be extremely simple to understand and use, require as little configuration as possible and it had to have as few dependencies as possible.
It shouldn’t force developers to have to write their model classes in a particular way and in fact it should allow the individual developer to decide whether to hide the underlying Sitecore API or expose it as part of the data model depending on the requirements of the solution in question.
It should automate the most common tasks such as retrieving an item from Sitecore, instantiate the desired model class and making the model instance available to the UI layer but it should also be usable in the other architectural layers in all situations where one would need to bind a Sitecore item to any kind of model class.
It should have support for Sitecore MVC.
It should work well as an API and comply with the basic SOLID design principals such as open for extension closed for modification, IoC, and dependency injection. In other words it should be possible to change all aspects of the framework behavior without having to decompile and alter the code.
And above all it should include some kind of validation mechanism to ensure that model class requirements are met when binding an item to a model and mechanisms to prevent invalid item data from causing page wide runtime errors.
With all these requirements in mind I set about creating the ItemBinding framework almost a year ago and as luck would have it at the time I was fortunate enough to become lead architect on what can only be called a fairly large enterprise level solution that was the perfect proving grounds. After a few months of rooting out various small design flaws I was ready to introduce the framework to my colleagues at Pentia where it was very well received and it has since been used as the basis for a couple of other solutions with hopefully many more to follow.
So the initial introduction of the framework was a success and as success should be shared I feel that it is now time to share it on a larger scale hoping that it will also prove useful to others.
Demonstration
Now of course no introduction is ever complete without a small demonstration so let’s pretend that we have a very rudimentary Document template in Sitecore that contains a single line title field, a rich text body field and an image field and we want to render an item based on the Document template in a DocumentView sublayout.
First this would be the document model class:
[RequiredBaseTemplate("{7F97671B-E1CA-4537-823C-230A7EAC4DED}")] public class Document : ItemModel { public Document(Item item) : base(Item item) { } public readonly ID TitleFieldId = new ID("{82B7DEB1-293A-49F4-8434-57B9B62F420F}"); public readonly ID BodyFieldId = new ID("{D642174A-591B-42B2-82BA-CFED87CE7B67}"); public readonly ID ImageFieldId = new ID("{15BB6EFA-2CDF-4F43-B14F-B682C09B329E}"); }
The most important thing to mention about the model class is that it can be any way you want it – literally. The framework only has one requirement when it comes to the model class and that is that it has to have a constructor that accepts an item. Why? Well since the framework is called Sitecore ItemBinding it would seem a bit silly without an item somewhere in the mix. Apart from that however you can decide exactly how the model class should look and if you want to hide everything related to Sitecore then fine by me. In this example however I have chosen the most primitive form that I could come up with. The most noteworthy part is the RequiredBaseTemplate attribute. This attribute tells the underlying framework that an item can only be bound to this model class if it inherits from the specified template. This is done through something called binding contracts and as the framework is completely extensible you can create your own contracts either by creating new class attributes for the default binding contract or by inventing an entirely new binding contract scheme. It could be based on what day of the week it is – the weather forecast – basically anything you could think of. The ItemModel base class is just a class that holds the item that was passed to the constructor.
Now on to the DocumentView sublayout codebehind
using ItemBinding.Presentation; using ItemBindingExamples.Model; public partial class DocumentView : ModelBoundUserControl<Document> { }
Well it doesn’t really contain any code and that is the whole idea behind the framework. If you don’t need it you don’t write it – the framework will provide the default behavior needed to bind the item. So the only thing we need to specify is that the class should inherit from ModelBoundUserControl which in turn inherits from a standard UserControl. Apart from that we only have to specify the type of model class we want the ModelBoundUserControl to populate and by default it will try to use the data source item if provided or default to the context item. If you want to provide some other item you can override the SourceItem property of the ModelBoundUserControl and equally if you want to control the way the model class is instantiated you can even provide a custom model factory.
And finally the DocumentView sublayout markup file
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="DocumentView.ascx.cs" Inherits="DocumentView"> <%@ Register TagPrefix="sc" Namespace="Sitecore.Web.UI.WebControls" Assembly="Sitecore.Kernel"> <div class="document"> <h1> <sc:Text Item="<%# Model.InnerItem %>" Field="<%# Model.TitleFieldId %>" runat="server" /> </h1> <p> <sc:Image Item="<%# Model.InnerItem %>" Field="<%# Model.ImageFieldId %>" runat="server" /> <sc:Text Item="<%# Model.InnerItem %>" Field="<%# Model.TextFieldId %>" runat="server" /> </p> </div>
The only thing to note here is the Model instance that exposes the model class instance.
Summary
So what is the ItemBinding framework?
Well in short it is a framework designed to eliminate as much boiler plate code as possible while at the same time staying as open as possible to facilitate the specialized preferences of the individual developer and it contains a long awaited and sorely needed validation mechanism to prevent runtime errors due to invalid data.
Where to go next?
If you want to see some more examples of how to use the framework or read the full documentation that goes into details about how to handle advanced stuff such as custom model factories, automatic binding of child items or items in multi or single select fields, custom binding contracts, handling multiple Sitecore template inheritance and much more please visit the project’s GitHub wiki at https://github.com/BoBreiting/SitecoreItemBinding/wiki
The source code and binaries are on GitHub https://github.com/BoBreiting/SitecoreItemBinding and the binaries are also available through Sitecore Marketplace https://marketplace.sitecore.net/en/Modules/Sitecore_ItemBinding.aspx or directly in Visual Studio via NuGet – search for ItemBinding.
I truely hope that this will prove useful to some of you and that it will save you from typing just as much code as it has saved me and my colleagues.