public async Task Invoke(IDictionary <string, object> environment) { var sw = new Stopwatch(); var req = new RazorRequest(environment); ITrace trace = Tracer.ForRequest(req); using (trace.StartTrace()) { trace.WriteLine("Received {0} {1}", req.Method, req.Path); if (!IsUnder(VirtualRoot, req.Path)) { // Not for us! await NextApp(environment); return; } // Step 1. Route the request to a file RouteResult routed = await Router.Route(req, trace); if (!routed.Success) { // Also not for us! await NextApp(environment); return; } trace.WriteLine("Router: '{0}' ==> '{1}'::'{2}'", req.Path, routed.File.Name, routed.PathInfo); // Step 2. Use the compilation manager to get the file's compiled type sw.Start(); CompilationResult compiled = await CompilationManager.Compile(routed.File, trace); sw.Stop(); if (!compiled.Success) { trace.WriteLine("Compiler: '{0}' FAILED", routed.File.Name); throw new CompilationFailedException(compiled.Messages, compiled.GeneratedCode); } if (compiled.SatisfiedFromCache) { trace.WriteLine("Retrieved compiled code from cache in {0}ms", sw.ElapsedMilliseconds); } else { trace.WriteLine("Compiled '{0}' in {1}ms", routed.File.Name, sw.ElapsedMilliseconds); } sw.Reset(); // Step 3. Construct an instance using the PageActivator Type type = compiled.GetCompiledType(); ActivationResult activated = Activator.ActivatePage(type, trace); if (!activated.Success) { trace.WriteLine("Activator: '{0}' FAILED", type.FullName); throw new ActivationFailedException(type); } trace.WriteLine("Activator: '{0}' SUCCESS", type.FullName); // Step 4. Execute the activated instance! await Executor.Execute(activated.Page, environment, trace); } }