Here’s some quick notes for getting started with the Spark View Engine on ASP.NET MVC, including setting up a container (Castle Windsor).

Spark

  1. Reference the Spark assemblies Spark.dll, Spark.Web.Mvc.dll, and SparkLanguage.

  2. Configure and add the view engine in the MvcApplication class (full class below)

    var settings = new SparkSettings() .SetDebug(true) //.SetPageBaseType(“Your.NonDefault.BaseSparkView”) //.AddAssembly(“YourAssembly”) .AddNamespace(“System”) .AddNamespace(“System.Collections.Generic”) .AddNamespace(“System.Linq”) .AddNamespace(“System.Web.Mvc”) .AddNamespace(“System.Web.Mvc.Html”);

    ViewEngines.Engines.Add(new SparkViewFactory(settings));

  3. Add an Application.spark file to the Shared Views folder. The engine looks for this file as the site master layout file. It will also look for one with the controller name to use for views related to that controller, ex, Home.spark for the HomeController.

    <use content="title" />

Apart from the general syntax, there are two things to note both regarding the Use tag. File looks for other views in the shared folder to render. While the content looks for content to render in it’s place which can be set in a sub view, as below. content=”view” is the view being rendered.

  1. The view, Index.spark, is just a normal view. The tag defines the content used for the title in the Application.spark view above.

    My Home Page </assets:title>

    ${"Hello world"}

    ${Guid.NewGuid().ToString("n")}

The documentation on the Spark site is pretty good.

Container Setup

Thanks to Matt Halls post for pointing me to the integration point for adding a container to MVC for controller creation, the IControllerFactory.

public class ControllerFactory : IControllerFactory
{
    private readonly IWindsorContainer container; 
    public ControllerFactory(IWindsorContainer container)
    {
        container = container;
    }

    public IController CreateController(RequestContext requestContext, string controllerName)
    {
        return (IController) container.Resolve(controllerName.ToLowerInvariant() + "controller"); 
    }

    public void ReleaseController(IController controller)
    {
        container.Release(controller);
    }
}

Next setup the container in the MvcApplication class and set the factory in MVC with the ControllerBuilder.Current.SetControllerFactory method. Also register the controllers in the container.

public class MvcApplication : HttpApplication
{
    private WindsorContainer container; 
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
  
        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );
    }
  
    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
  
        ControllerBuilder.Current.SetControllerFactory(GetControllerFactory());
  
        var settings = new SparkSettings()
            .SetDebug(true)
            //.SetPageBaseType("Your.NonDefault.BaseSparkView")
            //.AddAssembly("YourAssembly")
            .AddNamespace("System")
            .AddNamespace("System.Collections.Generic")
            .AddNamespace("System.Linq")
            .AddNamespace("System.Web.Mvc")
            .AddNamespace("System.Web.Mvc.Html");
  
        ViewEngines.Engines.Add(new SparkViewFactory(settings));
    }
  
    private IControllerFactory GetControllerFactory()
    {
        container = new WindsorContainer();
  
        container.Register(AllTypes 
              .Of<IController>()
              .FromAssembly(typeof (HomeController).Assembly)
              .Configure(c => c.Named(c.ServiceType.Name.ToLowerInvariant()).LifeStyle.Transient));

        container.AddFacility("logging", new LoggingFacility(LoggerImplementation.Trace));
  
        return new ControllerFactory(_container);
    }
}