Using InferType with Glass Mapper for Sitecore

Search for a command to run...

No comments yet. Be the first to comment.
Polly is great library for easily configuring different kinds of policies around code execution, be it retry, circuit breaker, caching or lots of other things. It's probably most often used around HTTP requests. If you haven't heard about it you defi...

This is part 2 of my series on unit testing in .NET (C#) and will be about my conventions regarding naming unit tests, how to structure them and which parts to test. And lastly I will help you increase readability of assertions and potential error me...

I feel like unit testing is very important and very beneficial in a lot of ways. It helps with not breaking existing functionality and thereby also making you more confident in changing code without fear of breaking important stuff. Often it also mak...

I've been working with Swagger through NSwag a lot recently and also needed to get it to work when hidden behind a reverse proxy - i.e. another service forwarding a request to the service exposing the Swagger UI. Some of the issues I've had along the...

The other day I was writing a unit test to verify what was supposed to happen when a Task would throw an exception when awaited. It wasn't as straight forward as I first assumed, but I quickly found this Stack Overflow post that helped me: https://st...

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.
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.
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.
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.