SDL Web 8 – DXA .NET Extension Points – The ModelBuilder

Over the last 6 months, I have started using SDL Web 8 in anger – working with 3 different projects going live. I’ve not been sharing much but hope to change that this year.

This post is going to be a short technical post but it was a neat trick that really helped us out on a project – on another project where we had a similar requirement we struggled and ended up using a mechanism which I wasn’t totally happy with.

DXA has good support for View Models, which has become the de facto standard for working with DD4T data. DXA’s flavour of model binding, also called Semantic Mapping, allows you to declaratively bind your C# models to your SDL Web/Tridion Schema by annotating models with C# Attributes.

This is a really nice approach and can speed development, makes for more robust code and makes your views very readable since there is less of a reliance on key value pairs.

An example View Model might look like this:

The SemanticProperty attributes contain the XML names of your Schema. There are more complicated examples and plenty has been written on how to do semantic mapping. Anyway, back to our problem.

The situation occurred when we had a requirement for collections which could contain different types of items. This was designed as a Component List Schema with a multi-valued Compoennt Link field.

This Schema was linked with Accordions and Tabs Component Templates. The requirement was that many different Components could appear within these Accordions or Tabs. There are a few ways to approach this problem in SDL Web / Tridion. The Component List is one approach.

In traditional Tridion Templating it is quite easy to run different templates based on what Schema is in a Component Link field. In DXA, however, there is a bit of “magic” going on with model binding which means things aren’t as simple.

To do model binding, you have to tell DXA what ViewModels you have available. This is done in the RegisterAllViewModels method within the Area Registration file for your module with lines of code such as the below:

This tells DXA that there is a CollectionContentAccordion which uses the model ContentCollectionEntity. The View is specified as metadata on the Component Template and DXA uses this link to create the appropriate model class when it encounters that Component Template.

The ContentCollectionEntity maps to the Component List Schema like so:

Within that it has the CollectionItemEntity which is an Embedded Schema – the reasoning behind this was that these collections needed to contain Components which can map to more than one Component Template and after assessing the requirements we decided to use Keywords to store template names (a controversial choice but not one for this post).

Now we can see above that the CollectableEntity “item” field. This field can store any type that is a subclass of the CollectableEntity type. This is great from an object oriented perspective and meets our requirement to store many different types of Component Presentation within the tabs or accordions etc.

However, DXA’s model binder has no way of knowing which CollectableEntity we mean when we’re rendering this collection.

Enter the Module Builder, with some pretty simple code we can override the DefaultModelBuilder’s  “BuildEntityModel” method and change the baseModelType to match the one we need based on the Schema – allowing us to pass the correct Model to our view and reduce a lot of duplicated code.

We thought this was quite smart – but there was one caveat. In order to register the Model Builder, you need to add it to the modelBuilderPipeline in Web.config as below:

Note our comment below – we did find a reference to this as an extension points in a presentation from Bart Koopman and decided to accept the risk that we may need to refactor this code later if SDL change the extension point in a future version of DXA.

Did we make the right choice? The alternative to what we did involved some pretty ugly manual mapping code or a god-object which mapped to all the schemas and then using a flakey check for specific properties to decide what to render.

One thought on “SDL Web 8 – DXA .NET Extension Points – The ModelBuilder

  1. Thanks for the post, Rob, which I found while looking for how customers and implementers treat vocabularies and mappings.

    I don’t see the use of keywords mapping to Component Templates as controversial, per se. You needed to model a way for editors to select something with some context (in this case a selection). Ideally the system would let you add such “contextual” options for links (Component Presentation metadata FTW!).

    For your last question, in the end, such mappings need to live somewhere. That might be anything from XML configuration to configuration Components to “magic” naming conventions. At long as the implementation knows where these settings live and they’re not based on hard-coded system identifiers (i.e. not tcm uris), you’re covered for upgrades. I am in favor of auto-documentation and “in-system” help when possible.

Leave a Reply

Your email address will not be published. Required fields are marked *