public static string CompileToStream(bool enableLogging, string rootDir, string[] referenceAssemblies, string outputAssemblyName, Stream outputStream) { if (!rootDir.EndsWith(Path.DirectorySeparatorChar.ToString())) { rootDir += Path.DirectorySeparatorChar.ToString(); } EnableLogging = enableLogging; Log("Creating Razor engine..."); var engine = RazorEngine.Create(builder => { var defaultCSharpLoweringPhase = builder.Phases.OfType <IRazorCSharpLoweringPhase>().Single(); builder.Phases.Remove(defaultCSharpLoweringPhase); builder.Phases.Add(new VirtualDomCSharpLoweringPhase(defaultCSharpLoweringPhase)); builder.SetNamespace("Views"); builder.SetBaseType(typeof(RazorComponent).FullName); builder.ConfigureClass((codeDoc, classNode) => { classNode.Name = RazorComponent.GetViewClassName(rootDir, codeDoc.Source.FileName); if (!string.IsNullOrEmpty((string)codeDoc.Items["DetectedBaseClass"])) { classNode.BaseType = (string)codeDoc.Items["DetectedBaseClass"]; } AddIComponentRazorViewFactoryImplementation(classNode); var layoutProperty = new CSharpStatementIRNode { Parent = classNode, Source = null }; classNode.Children.Add(layoutProperty); layoutProperty.Children.Add(new RazorIRToken { Kind = RazorIRToken.TokenKind.CSharp, Parent = classNode, Content = $"protected override string Layout {{ get {{ return \"{ codeDoc.Items["DetectedLayout"] ?? string.Empty }\"; }} }}" }); }); }); Log("Compiling Razor files to C#..."); var filenames = GetFilesToCompile(rootDir); var syntaxTrees = GetSyntaxTrees(engine, rootDir, filenames); Log("Compiling C#..."); var modelAssemblyRefs = referenceAssemblies .Select(a => MetadataReference.CreateFromFile(Path.GetFullPath(a))) .Cast <MetadataReference>() .ToList(); CompileToFile(syntaxTrees, modelAssemblyRefs, outputAssemblyName, outputStream); return($"Compiled {syntaxTrees.Count} view(s) as {outputAssemblyName}"); }
internal static Component MountPageFromUrl(string url, BlazorContext context) { // By holding the _currentPageComponent in a static property, we ensure that it doesn't // get GCed while the user can still see and try to interact with it. // TODO: Instead of just using "MountAsPage" which destroys the entire previous element content, // somehow find the nearest common layout ancestor between the old and new page, and retain // the DOM/vdom up to and including that layout, and just insert the new sequence of child // layouts and the new page into it. _currentPageComponentPath = UrlToComponentPath(url); return(_currentPageComponent = RazorComponent .Instantiate(_currentPageComponentPath, context) .MountAsPage(_mountInElementSelector)); }
internal static void OnNavigation(string descriptor) { var parsed = MiniJSON.Json.Deserialize(descriptor) as Dictionary<string, object>; var url = (string)parsed["url"]; // By holding the _currentPageComponent in a static property, we ensure that it doesn't // get GCed while the user can still see and try to interact with it. // TODO: Instead of just using "MountAsPage" which destroys the entire previous element content, // somehow find the nearest common layout ancestor between the old and new page, and retain // the DOM/vdom up to and including that layout, and just insert the new sequence of child // layouts and the new page into it. _currentPageComponentPath = UrlToComponentPath(url); _currentPageComponent = RazorComponent .Instantiate(_currentPageComponentPath) .MountAsPage(_mountInElementSelector); }