Using InferType with Glass Mapper for Sitecore

Using InferType with Glass Mapper for Sitecore

The InferType setting of Glass Mapper is a great feature that enables you to use inheritance within your Sitecore templates and the models in your code. However, I personally had some issues getting it to work correctly, so here is a short overview of some of the ways you can configure this and how to decorate your models.

Model decoration

Let us say we have some kind of content page, which has some text spots.

public class ContentPage
{
    [SitecoreField(Setting = SitecoreFieldSettings.InferType)]
    public IEnumerable<TextSpot> Spots { get; set; }
}

public abstract class TextSpot
{
    [SitecoreField]
    public virtual string Text { get; set; }
}

Spots is a multilist field and it needs to be decorated with the SitecoreField attribute and have the InferType setting set.

Next up is the different types of TextSpot:

[SitecoreType(TemplateId = "{0EE93413-BD27-44E4-914F-4A94FBED83E9}")]
public class NormalTextSpot : TextSpot
{
    public virtual string GetSnippet()
    {
        return Text.Substring(0, 10);
    }
}

[SitecoreType(TemplateId = "{2593DDC6-B5E9-4B1E-ACDC-DDF970D9C264}")]
public class WideTextSpot : TextSpot
{
    public virtual string GetSnippet()
    {
        return Text.Substring(0, 20);
    }
}

If you want Glass Mapper to be able to use the class matching you template in Sitecore you have to add the SitecoreType attribute and set the TemplateId property. When using InferType, Glass Mapper will try to find a type of TextSpot that has TemplateId matching the template of the item being mapped.

Configuration

You have now made sure of everything mentioned above, but it is not working correctly? You might be getting an instance of the correct type (NormalTextSpot or WideTextSpot in this case) but the method/properties are not returning anything? This is because you need to force Glass Mapper to load the types when your application start. As explained by Mike Edwards (the guy behind Glass Mapper) onstackoverflow this is done in GlassMapperScCustom.cs (located in the App_Start folder) like this:

public static IConfigurationLoader[] GlassLoaders()
{
    /* USE THIS AREA TO ADD FLUENT CONFIGURATION LOADERS
     *
     * If you are using Attribute Configuration or
     * automapping/on-demand mapping you don't need to do anything!
     *
     */

    var attributes = new AttributeConfigurationLoader("Your.Assembly.Name");
    return new IConfigurationLoader[] { attributes };
}

This will make sure all of your types decorated with the SitecoreType attribute are loaded at application start and Glass Mapper should now be able to infer the type correctly.

Combined with TDS code generation

If you are using Glass Mapper together with code generation in Team Development for Sitecore (TDS) you might run into special cases, where you don’t want to load all types. To only load specific types you can easily create your own IConfigurationLoader that works exactly like the AttributeConfigurationLoader above but only for specific types.

public class CustomGlassConfigurationLoader : IConfigurationLoader
{
    public IEnumerable<AbstractTypeConfiguration> Load()
    {
        return new List<AbstractTypeConfiguration>
        {
            new AttributeTypeLoader(typeof (NormalTextSpot)).Load().FirstOrDefault(),
            new AttributeTypeLoader(typeof (WideTextSpot)).Load().FirstOrDefault(),
        };
    }
}

You then simply return a new instance of that class in the GlassLoaders() method like before.

public static IConfigurationLoader[] GlassLoaders()
{
    /* USE THIS AREA TO ADD FLUENT CONFIGURATION LOADERS
     *
     * If you are using Attribute Configuration or 
     * automapping/on-demand mapping you don't need to do anything!
     *
     */

    return new IConfigurationLoader[] { new CustomGlassConfigurationLoader() };
}

Glass Mapper will now only be able to infer the two specified types – NormalTextSpot and WideTextSpot.