Allow Glass to determine your models from your compile views.

This documentation applies to Glass.Mapper.Sc 4.3+.

 

If you are using compile views as describe by Kam Figy and now supported in Sitecore 8.2 (it is also possible to make this work for earlier versions) you can now get Glass to automatically determine the type required by the view when using View Renderings.

To do this we need to supply a custom IViewTypeResolver to the Glass.Mapper.Sc.Pipelines.Response.GetModelFromView which will do the work for us. 

First create the following class:

using System;
using System.Reflection;
using System.Web.Mvc;
using Glass.Mapper.Sc.Pipelines.Response;
using RazorGenerator.Mvc;
using Sitecore.Mvc.Common;

namespace Custom
{
    public class CompileViewTypeFinder : IViewTypeResolver
    {
        public Type GetType(string path)
        {

            ViewContext current = ContextService.Get().GetCurrent<ViewContext>();
            var partial = System.Web.Mvc.ViewEngines.Engines.FindPartialView((ControllerContext)current, path);
            var view = partial.View as PrecompiledMvcView;

            var type = typeof(PrecompiledMvcView).GetField("_type", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(view)
                as Type;

            Type baseType = type.BaseType;

            if (baseType == null || !baseType.IsGenericType)
            {
                Sitecore.Diagnostics.Log.Warn(string.Format(
                    "View {0} compiled type {1} base type {2} does not have a single generic argument.",
                    path,
                    type,
                    baseType), this);

                return typeof(NullModel);
            }

            Type proposedType = baseType.GetGenericArguments()[0];
            return proposedType == typeof(object)
                ? typeof(NullModel)
                : proposedType;
        }
    }
}

Next replace the default IViewTypeResolver used by the GetModelFromView class. We have chained this so that we can use CSHTML files that are not compiled as well as compile views, this can be setup in the PostLoad of the GlassMapperScCustom class:

public static void PostLoad(){
   GetModelFromView.ViewTypeResolver = new ChainedViewTypeResolver(
                new IViewTypeResolver[] {
                    new CompileViewTypeFinder(),
                    new RegexViewTypeResolver() });

Now sit back and enjoy quicker Sitecore load times and less typing!