views:

63

answers:

1

After pushing my asp.net mvc (with spark view engine) project to our live server yesterday I've started getting a strange error. Everything works fine initially, but after some time (maybe 30 minutes) the views start throwing "Dynamic view compilation failed" errors and complaining about namespaces not existing. The assemblies for the namespaces listed are in the bin (since it did work initially). I'm using the spark view engine on other websites running on the same box and have never seem this issue. What is causing these views to stop working?

+1  A: 

As qstarin mentioned, recycling the AppPool does seem to kick the assemblies out. Here's the original Spark discussion regarding the issue:

http://groups.google.com/group/spark-dev/browse_thread/thread/dbee06a0d1b2766f#

In general, it seems the issue is caused by Spark trying to compile the views BEFORE the AppPool has had time to load all of the assemblies.

Picking the assemblies one-by-one still seemed to cause random glitches for me, so I tweaked the code in that discussion post and load it as the first line in Application_Start(). Since then, I've pushed out a dozen or so applications over time and haven't seen the precompile issue once.

private void PreLoadAssemblies()
{
    // Deal with the compiling issue with Spark.
    var initialAssemblies = AppDomain.CurrentDomain.GetAssemblies();
    var di = new DirectoryInfo(Server.MapPath("~/bin"));
    var files = di.GetFiles("*.dll");
    foreach (var fi in files)
    {
        var found = false;
        //already loaded? 
        foreach (var asm in initialAssemblies)
        {
            var a = Assembly.ReflectionOnlyLoadFrom(fi.FullName);
            if (asm.FullName == a.FullName)
                found = true;
        }

        if (!found)
            Assembly.LoadFrom(fi.FullName);
    }
}

and then your Application_Start():

protected override void Application_Start(object sender, EventArgs e)
{
    PreLoadAssemblies();
    base.Application_Start(sender, e);

    //Whatever else you normally do in Application_Start():
    MvcHandler.DisableMvcResponseHeader = true;
    ViewEngineManager.Configure(ViewEngines.Engines);
    RouteManager.RegisterRoutes(RouteTable.Routes);
    new InjectionManager().StartNinject();
}
David Longnecker