public Type CompileFile(RazorViewCompilationData view, IEnumerable <Assembly> assembliesToReference, bool includeDebugInformation = false, string debugFilePath = null) { var host = new RazorEngineHost(new CSharpRazorCodeLanguage()); foreach (var @namespace in this.razorConfiguration.GetDefaultNamespaces().Union(this.defaultNamespaces)) { host.NamespaceImports.Add(@namespace); } var engine = new RazorTemplateEngine(host); // host.EnableInstrumentation = includeDebugInformation; // host.InstrumentedSourceFilePath = debugFilePath; GeneratorResults razorResult; using (var textReader = new StringReader(view.ViewContents)) razorResult = engine.GenerateCode(textReader, view.Name, "", debugFilePath); var assemblies = new List <string>(); var appAssembly = GetApplicationAssembly(); assemblies.AddRange(this.defaultAssemblies); assemblies.Add(GetAssemblyPath(appAssembly)); // current app assemblies.AddRange(appAssembly.GetReferencedAssemblies().Select(GetAssemblyPath)); // assemblies referenced by current app assemblies.AddRange(AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic).Select(GetAssemblyPath)); // loaded assemblies (superset of above line?) // assemblies.AddRange(AssemblyRepository.GetApplicationAssemblies().Select(GetAssemblyPath)); // assemblies in app's folder // assemblies named by configuration var assemblyNames = this.razorConfiguration.GetAssemblyNames(); // TODO: cant just load here, use assembly repos to check uniqueness assemblies.AddRange(assemblyNames.Select(Assembly.Load).Select(GetAssemblyPath)); assemblies.AddRange(assembliesToReference.Select(GetAssemblyPath)); assemblies = assemblies.Distinct(p => Path.GetFileName(p).ToLowerInvariant()).ToList(); var compilerParameters = new CompilerParameters(assemblies.ToArray()); compilerParameters.IncludeDebugInformation = true; compilerParameters.TempFiles.KeepFiles = false; var codeProvider = new CSharpCodeProvider(); var compilationResults = codeProvider.CompileAssemblyFromDom(compilerParameters, razorResult.GeneratedCode); if (compilationResults.Errors.HasErrors) { var errors = compilationResults.Errors.OfType <CompilerError>().Where(ce => !ce.IsWarning).Select(error => String.Format( "[{0}] Line: {1} Column: {2} - {3}", error.ErrorNumber, error.Line, error.Column, error.ErrorText)).Aggregate((s1, s2) => s1 + "\n" + s2); //TODO: Format Errors nicely throw new ViewRenderException("Failed to compile view `" + view.Name + "`: " + errors); } var type = compilationResults.CompiledAssembly.GetType(view.Name); if (type == null) { throw new ViewRenderException($"Could not find type `{view.Name}` in assembly `{compilationResults.CompiledAssembly.FullName}`"); } // // if (Activator.CreateInstance(type) as RazorViewPage == null) // throw new ViewRenderException(string.Format("Could not construct `{0}` or it does not inherit from RazorViewPage", type)); return(type); }
public void CompileAndMergeFiles(IEnumerable <RazorViewCompilationData> viewCompilationDetails, string outputAssemblyName) { var host = new RazorEngineHost(new CSharpRazorCodeLanguage()); foreach (var @namespace in this.razorConfiguration.GetDefaultNamespaces().Union(this.defaultNamespaces)) { host.NamespaceImports.Add(@namespace); } var engine = new RazorTemplateEngine(host); var razorResults = viewCompilationDetails .Select(v => { var stringReader = new StringReader(v.ViewContents); return(engine.GenerateCode(stringReader, v.Name, "", v.Name)); }) .Select(r => r.GeneratedCode); var assemblies = new List <string>(); var appAssembly = GetApplicationAssembly(); assemblies.AddRange(this.defaultAssemblies); assemblies.AddRange(appAssembly.GetReferencedAssemblies().Select(GetAssemblyPath)); // assemblies referenced by current app assemblies.AddRange(AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic).Select(GetAssemblyPath)); // loaded assemblies (superset of above line?) //.AddRange(AssemblyRepository.GetApplicationAssemblies().Select(GetAssemblyPath)); // assemblies in app's folder // assemblies named by configuration var configuredAssemblyNames = this.razorConfiguration.GetAssemblyNames(); // TODO: cant just load here, use assembly repos to check uniqueness assemblies.AddRange(configuredAssemblyNames.Select(Assembly.Load).Select(GetAssemblyPath)); var assemblyNames = assemblies.Distinct(p => Path.GetFileName(p).ToLowerInvariant()).ToArray(); var outputAssemblyPath = Path.Combine(this.razorConfiguration.OutPath, outputAssemblyName + ".Views.Razor.dll"); var compilerParameters = new CompilerParameters(assemblyNames, outputAssemblyPath, true) { TempFiles = { KeepFiles = false } }; var codeProvider = new CSharpCodeProvider(); var compilationResults = codeProvider.CompileAssemblyFromDom(compilerParameters, razorResults.ToArray()); if (compilationResults.Errors.HasErrors) { var errors = compilationResults.Errors .OfType <CompilerError>() .Where(ce => !ce.IsWarning) .Select(error => $"[{error.ErrorNumber}] {error.FileName}: Line: {error.Line} Column: {error.Column} - {error.ErrorText}") .Aggregate((s1, s2) => s1 + "\n" + s2); //TODO: Format Errors nicely throw new ViewRenderException("Failed to compile dll `" + outputAssemblyPath + "`: " + errors); } var assembly = Assembly.LoadFrom(outputAssemblyPath); if (assembly == null) { throw new ViewRenderException("Error loading template assembly"); } }