Life Through A Lens – Data Modelling in Glass Mapper

When it comes to modelling data using Glass Mapper, we as developers can often find there is too much choice. In this post I will look at some of the common scenarios & considerations we as developers are likely to face and how I choose to approach mapping with Glass Mapper on the Sitecore platform.

Mapping the domain – Template models

When it comes to first considering Glass in your implementations (or possibly later), the common misconception and (in mine and Mike Edwards’ opinion) mistake is to attempt to create a 1 to 1 mapping between the template structure in Sitecore and the structure of your POCO’s.

Firstly, in choosing this option, developers will often very quickly discard concrete models in favour of the pure interface mapping structure as it can more closely mimic the multiple inheritance model in Sitecore. This is also a mistake – one of Glass Mapper’s strengths in my opinion is the ability to map to concrete objects. The primary advantage being that concrete models can easily have logic of their own that does not relate to the data structure – think of things like methods that conditionally return from multiple properties for example.

The second and slightly more critical error in this approach is simply that as described in Mappers and Wrappers. Glass Mapper utilises the data mapper pattern. By its nature, you pay a penalty for the number of properties you map.

Code Generation

I know the above almost directly precludes code generation (which in truth I am never a fan of) but hear me out. I often hear the standard argument of ‘it would take too long to write all of our models by hand’. I dispute this hugely. It really takes a handful of keystrokes to create an interface and give 2 / 3 properties – which we as developers have usually developed a string of automated movements to complete. Probably (in truth) not that many more than having to re-generate the model from TDS / Rocks and wait for it to complete.

If this rates in the top 50 biggest impacts on time to the developers in your team, I would salute your amazing development processes and like to see what you are doing so right (or you are lucky enough to be dealing with a build that small).

Add to this, most of the time, you don’t even have to annotate the classes with much if anything.

Another of Glass Mappers great strengths is in the fact you can manipulate and control your models unlike the frameworks that rely on generation – meaning you can easily annotate with [JsonProperty] or whatever to allow your models to be used effectively in other integrations.

Rendering Models

I personally don’t quite agree with the term ‘Rendering Models’ – it is something I refer to as it matches closely with this post by Glass Mapper’s founder – Mike Edwards a while ago. It is an article that is well worth a read, and explains much of the above in more depth. In essence the argument is to map what you use in your renderings. The reality in the modern Sitecore arena is that we, as developers, are having to deal with increasingly complicated integrations with other systems, and that in lots of cases now, the use of Glass as an ORM plays it part as an even bigger time saver than before.

Consider the ease of mapping to Json, Xml etc – all can be done on a regular POCO that Glass Mapper has mapped for you from Sitecore. I think a better term should be something like ‘Concise Models’.

Common Base Templates

In hearing the above, I often see / hear developers advocating the use of common base templates, explaining that you can cover things like item id, name, template id, template name, url and other common item fields.

In real world scenarios, this is also a bad practise and here is why.

Consider the following ‘base template’ implementation:

public interface IGlassBase
{
   Guid Id { get; set;}

   string Name { get; set; }

   string Url { get; set; }
}

This is a very common style of interface I see in Glass implementations in the wild.

Now in reality – consider an implementation that may be based on this, for example, lets take the modelling of a typical Call to Action.

public interface ICallToAction : IGlassBase
{
	string Title { get; set; }

	string Description { get; set; }

	Image Image{ get; set; }

	Link Link { get; set; }
}

Then – the chances are that the markup for this (front end guys – excuse my lazy html) will probably look something like this once converted to use Glass Mapper.

<div class=”cta grid-12”>
	@Html.Glass().RenderImage(x => x.Image)
	<h2>@Html.Glass().Editable(x => x.Title)</h2>
	<p>@Html.Glass().Editable(x => x.Description)</p>
	@Html.Glass().RenderLink(x => x.Link)
</div> 

So – here presents the first opportunity to consider your model hierarchy. How many of the fields that we have mapped are we now using? Simply => 4 = just over 50% of them.

So lets consider another common use case – the content listing – I have seen many developers create something like the in their implementations to allow the use of many items in a content listing scenario:

public interface INavigable : IGlassBase
{
   string Title { get; set; }

   string ShortDescription { get; set; }
}

Now in an average markup like the one below where Children is an IEnumerable:

@foreach(var child in Model.Children)
{
   <ul class=”content-listing”>
      <li>
          <a href=”@child.Url”>@child.Title</a>
          <span>@child.ShortDescription</span>
       </li>
   </ul>
}

Now with this implementation – we are faced with using equally few of our properties – just 3/5 – everything on IGlassBase is pretty much irrelevant.

This for simple .net types might not seem like that much, but under high load in performance tests specifically on Glass Mapper one of the biggest hotspots the level of interaction with the Sitecore Item’s fields.

You must consider how much work the server has to do for your beautifully flexible Sitecore ecosystem.

Granular & Concise Modelling
So here it is – I propose Granular and Concise mapping for Glass Mapper and it can be summed up as this.

‘Granular and concise models can be used individually or in combination to give the developer the concise model they require’.

So – how did I come to this point –

It is potentially a common misconception that the number of models Glass Mapper needs to know about will actually impact the performance of the framework. To be clear on this, this is only an impact on the first time the first object of a particular model type is loaded, and this is only the case when you haven’t pre-loaded the models in using an AttributeConfigurationLoader, FluentConfigurationLoader or added their configuration via Configuration Maps (which helps you configure using the Fluent Config API). If you do the latter, then the cost is paid when Glass is first initialised.

It is therefore perfectly feasible to map only what you use for the given application. If you don’t have something that matches exactly, then simply create another type that does.

So – broken down from the above examples you could opt to remap them like so.

public interface IItemId
{
	Guid Id { get; set; }
}

public interface IItemUrl
{
	string Url { get; set; }
}

public interface ITitle
{
	string Title { get; set; }
}

public interface IDescription
{
	string Description { get; set; }
}

// optional
public interface ITitleAndDescription : ITitle, IDescription
{
}

public interface IShortDescription
{
	string ShortDescription { get; set; }
}

//  optional
public interface ITitleAndShortDescription : ITitle, IShortDescription
{
}

public interface ICallToAction : ITitleAndDescription
{
	Image Image{ get; set; }

	Link Link { get; set; }
}

public interface INavigable : IItemUrl, ITitleAndShortDescription
{
}

You will notice there is in fact now no need to have anything mapped specifically for the navigable interface and there is also no fields being mapped that don’t need to be. If we thought about this in SOLID terms, this is a reasonable representation of .

This might on the face of it seem like interface explosion, and it kind of is. But in reality, you would only have such model for template fields that are reused on LOTS of templates. When you consider this across an entire solution, the majority of your templates will be built off of probably a handful of granular templates like the ones above.

The granular segregation of your base classes in my humble opinion is far far less likely to end in too many mapped and unused properties in your domain and therefore (in my opinion) provides a better base for a performant solution based upon Glass Mapper

The other great advantage to this proposed modelling is that when it comes to reusing your maps in non-Sitecore integrations, you can still very easily bunch together your regularly used interfaces in ways that you would not usually expect to have done within Sitecore.

Glass Caching

Something to note about the caching mechanisms on Glass Mapper is that they are based upon the REQUESTED type, so – for example – you may well choose to request (from the above) ITitleAndDescription from the cache, but pull IFullPage (which inherits ITitleAndDescription) from Sitecore itself. This is perfectly possible using the Glass Mapper Cache. This can provide great speed benefits with little risk (you only need to view the to see how quick it can be. Note – this was not the intended use, but is a very logical upshot of this modelling technique. You could even use something like the to share the first result from the server across all of your CD nodes. This too is something that is only allowed by a mapping pattern`.

View Models
In actual fact when you consider granular mapping as a practice, the reality of such translates near perfectly to your view models. In many cases, in contrary to some other respected developers. I still advocate the idea of using your Glass model classes directly in your views – in particular this is the case when using view renderings (which for knowledge at the time of writing are SIGNIFICANTLY faster than controller renderings).

Many developers see view renderings as an abomination. I see them simply as making Glass Mapper the controller and therefore fitting perfectly with the MVC pattern – each to their own, and that’s another debate entirely.

Model Reuse

Something else to consider is the following scenario.

I have now decided in my solution to add a second call to action with the same field names and number of fields as our first. However… The content editor this time needs to choose the image from a different location and the link from a different location within the Sitecore tree.

In Sitecore terms we are talking more or less about duplicating the existing Call To Action template and simply changing the Data Source property of the field (ok – so you might share a base class with Title / Link if you want 😉 ).

Now, assuming you have mapped your field by name (and in this case its simpler still since its going to AutoMap).

For this purpose, I personally would advocate the reuse of the original ICallToAction interface to represent this new template (something which I think you will find difficult to impossible using a wrapping based framework such as Synthesis or Fortis). This is because from a code point of view, we already have a concise template that relates to the fields we are going to use.

The reality of this in development may well result in the CallToAction view being reused, since the model is the same, the view has the same markup.

Conclusion

I think the best way to look at modelling in Glass is to apply Interface Segregation Principle to your models, multiple smaller interfaces will usually trump single larger ones since you can always combine variations of the smaller single interfaces. As a consequence, you may well find that your code relies less on things that it shouldn’t and I hope would result in developers being less lazy in simply adding everything to the common base (which again, happens a lot)

Furthermore, by forcing a developer to think about template reuse, model reuse, you start to think about your components much more as reusable. This can result in actually less presentation code to maintain (which in turn is awesome as not many of us like tracking down the css class change the front end guy HAD to make).

Utilise caching (in V4) to improve speed on granular requests

Consider the reuse of your model structure for non-Sitecore applications

Advertisements

One thought on “Life Through A Lens – Data Modelling in Glass Mapper

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s