Composite Reuse Principle in Sitecore Code Generation

Context

If you do Sitecore projects and have never tried to create strongly typed models then most likely you are doing something wrong. ūüôā Why? As soon as your project grows a bit, the logic becomes more complex or you decide to refactor a few components, you will suffer from all magic things –¬†strings, number, GUIDs.¬†Of cause, there are a few things that you can do about that.

Available Options

You could create a file with constants for templates and fields IDs, which would help you to keep references in one place and make them more manageable. However, this is a lot of manual work that you would need to do over and over again for maintaining the project and, honestly, I do not like that.

Ok, then we think about automation. You could write a code that would go through templates tree and generate a file. This is getting better but what about the type check? By providing a field name to the fields dictionary you won’t know the type of this field. So you need to come up with some kind of a¬†DTO object as a model and mapping, as you would use in any application with a¬†connection to services or database.

It looks like that next stop is an ORM framework of some kind as it might do dirty work for you. Decorate your models with attributes, call a factory method that would populate data to your models and you have a strongly typed class that will give you full benefits of compilation, type check, IntelliSense and yadda.

What if we train the code to create those models besides the constants? This would be our automatic code generation with blackjack and… you choose what comes next. And believe me, when you see 30 000 lines of autogenerated models and you do not need to change them manually this is a huge deal.

5 years ago we were writing a lot of code to generate code and wire up DTO with Sitecore and that code was web based, but now there are a few products like TDS and Unicorn (with additional modules) that would help you generate code. Tooling for code generation most likely would be the same for .NET frameworks – is it Text Template Transformation Toolkit or T4 and it is used in both products mentioned above. However, you would still need to tell them how to do that.

Code Generation Approaches

Code generation should create an object model that describes Sitecore templates and their fields. Sitecore can inherit fields from other templates but unlike the majority of the programming languages where you see inheritance concept, it supports multiple inheritance.

There are 3 approached that you can use to map Sitecore templates model to C# objects, which I will illustrate using Content and Meta templates referenced by the template Page.

Classes and Interface Inheritance

In this approach, interfaces are used to cover multiple inheritance of base templates. So, in this case, it would be possible to use both interfaces and classed, as classes would have the same flat model as the Sitecore fields dictionary provides. However, generated code would have tons of duplications as an implementation of same fields would be repeated over and over again (the field in Content class reimplemented in Page class). Also, you are losing the ability to reuse properties manually implemented in partial classes in derived classes, as inheritance done interfaces.


public interface IContent
{
  string Title { get; set; }
  string Text { get; set; }
}

public partial class Content : IContent
{
  public virtual string Title { get; set; }
  public virtual string Text { get; set; }
}

public interface IMeta
{
  string Keywords { get; set; }
  string Description { get; set; }
}

public partial class Meta: IMeta
{
  public virtual string Keywords { get; set; }
  public virtual string Description { get; set; }
}

public interface IPage : IContent, IMeta
{
  bool Searchable { get; set; }
}
public partial class Page : IPage, IContent, IMeta
{
  public virtual string Title { get; set; }
  public virtual string Text { get; set; }
  public virtual string Keywords { get; set; }
  public virtual string Description { get; set; }
  public virtual bool Searchable { get; set; }
}

Only Interface Inheritance

This is a trimmed down version of an approach above – it doesn’t have classes at all. Most of ORM frameworks would be able to work with it as they are generating proxy classes for those interfaces. However, you need to create an instance without ORM you would need to create your own implementation.¬†Also, additional functionality could be added only via extension methods.

public interface IContent
{
  string Title { get; set; }
  string Text { get; set; }
}

public interface IMeta
{
  string Keywords { get; set; }
  string Description { get; set; }
}

public interface IPage : IContent, IMeta
{
  bool Searchable { get; set; }
}

Composition Pattern

In a case of model generation using composition pattern, base templates are used as property types for a derived class. It is possible to reuse already defined in base classes implementations and extend them with partial (extended implementation of Content class would be available in Page class).
As any other approached this would have some drawbacks: it is not possible to define BasePage model and reference all derived pages using it.

public partial class Content
{
  public virtual string Title { get; set; }
  public virtual string Text { get; set; }
}

public partial class Meta
{
  public virtual string Keywords { get; set; }
  public virtual string Description { get; set; }
}

public partial class Page
{
  public Page () {}
  public Page (Content content, Meta meta)
  {
    this.ContentComp = content;
    this.MetaComp = meta;
  }
  public virtual Content ContentComp { get; set; }
  public virtual Meta MetaComp { get; set; }
  public virtual bool Searchable { get; set; }
}

For an ORM frameworks like GlassMapper¬†composition might be a bit tricky as all fields are represented in a Sitecore Item as a dictionary, which is mapped to same flat class or interface. However, it could be solved by adding a simple method that would map a property to an item itself (I’ve actually sent a pull request to Glass, which hopefully will make to a release soon).

Composition over Inheritance

Over the time I’ve tried all 3 variant and would suggest using the last one due to following reasons:

  • To favor composition over inheritance is a design principle that gives the design higher flexibility, giving business-domain classes and more stable business domain in the long term.
  • In term of Sitecore, while physically you items templates inherit fields meta-information, but from implementation perspective models HAS-A¬†behavior related to those fields.
  • Simplifies code-generation, minimize duplication and allow you to¬†extend behaviors model via partials.
  • Allows you to generate code sections using reflection, restoring minimal templates info from DLLs.

The last point I will describe in the separate post.


Follow me on twitter @true_shoorik. Would be glad to discuss ideas above in comments.

Composite Reuse Principle in Sitecore Code Generation

4 thoughts on “Composite Reuse Principle in Sitecore Code Generation

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