Search code examples
c#asp.netsitecoresitecore6glass-mapper

Check Glass Mapper V3 types at runtime


Using Glass Mapper V3, is it possible to check whether a Sitecore item supports a specific Glass Mapper class/interface?

Given these classes

[SitecoreType]
public partial interface IPage : IGlassBase
{
  // ... some properties here ...
}

[SitecoreType]
public partial interface IRateableItem : IGlassBase
{
  // ... some properties here ...
}

I would like to do something like this

var context = SitecoreContext();
var item = context.GetCurrentItem<IRateableItem>();
if (item != null)
  // it's an item that is composed of the Rateable Item template

Unfortunately, if I do that, I do get an item of the type IRateableItem returned, regardless of whether the current item is composed of that template or not.


Solution

  • Dan

    Another solution would be to create a custom task that runs in the ObjectConstruction pipeline.

    Something like this:

    public class LimitByTemplateTask : IObjectConstructionTask
    {
        private static readonly Type _templateCheck = typeof (ITemplateCheck);
    
        public void Execute(ObjectConstructionArgs args)
        {
            if (args.Result != null)
                return;
    
            if ( _templateCheck.IsAssignableFrom(args.AbstractTypeCreationContext.RequestedType))
            {
                var scContext = args.AbstractTypeCreationContext as SitecoreTypeCreationContext;
                var config = args.Configuration as SitecoreTypeConfiguration;
    
                var template = scContext.SitecoreService.Database.GetTemplate(scContext.Item.TemplateID);
    
                //check to see if any base template matched the template for the requested type
                if (template.BaseTemplates.All(x => x.ID != config.TemplateId) && scContext.Item.TemplateID != config.TemplateId)
                {
                    args.AbortPipeline();
                }
            }
        }
    }
    
    
    public interface ITemplateCheck{}
    

    You would then change you IRateableItem inteface to have the template ID it needs to match and inherit from ITemplateCheck:

    [SitecoreType(TemplateId = "CF9B175D-872E-439A-B358-37A01155EEB1")]
    public interface IRateableItem: ITemplateCheck, IGlassBase{}
    

    Finally you will need to register the new task with the Castle IOC container in GlassMapperScCustom:

        public static void CastleConfig(IWindsorContainer container){
            var config = new Config();
    
            container.Register(
                Component.For<IObjectConstructionTask>().ImplementedBy<LimitByTemplateTask>(),
                );
            container.Install(new SitecoreInstaller(config));
        }
    

    I haven't had a chance to test this so let me know if there are any problems.