From e8d31697ad8cf227034de8119c3f3f14e164dab9 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 14 Feb 2020 08:35:06 -0800 Subject: [PATCH] Add an option to enable runtime compilation (#18648) --- ...etCore.Mvc.Razor.RuntimeCompilation.csproj | 1 + .../src/Properties/AssemblyInfo.cs | 4 ++++ .../RazorRuntimeCompilationHostingStartup.cs | 17 ++++++++++++++ .../RazorPagesWeb-CSharp.csproj.in | 9 ++++---- .../StarterWeb-CSharp.csproj.in | 9 ++++---- .../.template.config/dotnetcli.host.json | 4 ++++ .../.template.config/template.json | 6 +++++ .../.template.config/vs-2017.3.host.json | 9 ++++++++ .../Properties/launchSettings.json | 22 +++++++++++++----- .../.template.config/dotnetcli.host.json | 4 ++++ .../.template.config/template.json | 6 +++++ .../.template.config/vs-2017.3.host.json | 9 ++++++++ .../Properties/launchSettings.json | 22 +++++++++++++----- src/ProjectTemplates/test/MvcTemplateTest.cs | 19 +++++++++++++++ .../test/RazorPagesTemplateTest.cs | 23 +++++++++++++++++++ 15 files changed, 144 insertions(+), 20 deletions(-) create mode 100644 src/Mvc/Mvc.Razor.RuntimeCompilation/src/RazorRuntimeCompilationHostingStartup.cs diff --git a/src/Mvc/Mvc.Razor.RuntimeCompilation/src/Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.csproj b/src/Mvc/Mvc.Razor.RuntimeCompilation/src/Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.csproj index 1476267dfc..ee568fe903 100644 --- a/src/Mvc/Mvc.Razor.RuntimeCompilation/src/Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.csproj +++ b/src/Mvc/Mvc.Razor.RuntimeCompilation/src/Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.csproj @@ -12,6 +12,7 @@ + diff --git a/src/Mvc/Mvc.Razor.RuntimeCompilation/src/Properties/AssemblyInfo.cs b/src/Mvc/Mvc.Razor.RuntimeCompilation/src/Properties/AssemblyInfo.cs index 472b09032a..bb42a1ab38 100644 --- a/src/Mvc/Mvc.Razor.RuntimeCompilation/src/Properties/AssemblyInfo.cs +++ b/src/Mvc/Mvc.Razor.RuntimeCompilation/src/Properties/AssemblyInfo.cs @@ -2,6 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Runtime.CompilerServices; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation; [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] + +[assembly: HostingStartup(typeof(RazorRuntimeCompilationHostingStartup))] \ No newline at end of file diff --git a/src/Mvc/Mvc.Razor.RuntimeCompilation/src/RazorRuntimeCompilationHostingStartup.cs b/src/Mvc/Mvc.Razor.RuntimeCompilation/src/RazorRuntimeCompilationHostingStartup.cs new file mode 100644 index 0000000000..62eee8072a --- /dev/null +++ b/src/Mvc/Mvc.Razor.RuntimeCompilation/src/RazorRuntimeCompilationHostingStartup.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; + +namespace Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation +{ + internal sealed class RazorRuntimeCompilationHostingStartup : IHostingStartup + { + public void Configure(IWebHostBuilder builder) + { + // Add Razor services + builder.ConfigureServices(services => RazorRuntimeCompilationMvcCoreBuilderExtensions.AddServices(services)); + } + } +} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/RazorPagesWeb-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/RazorPagesWeb-CSharp.csproj.in index ab090ad09e..5157f8936f 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/RazorPagesWeb-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/RazorPagesWeb-CSharp.csproj.in @@ -7,16 +7,16 @@ 1 True Company.WebApplication1 + false - - - + + + - @@ -26,6 +26,7 @@ + diff --git a/src/ProjectTemplates/Web.ProjectTemplates/StarterWeb-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/StarterWeb-CSharp.csproj.in index 70d65ede37..9b38d19da0 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/StarterWeb-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/StarterWeb-CSharp.csproj.in @@ -7,16 +7,16 @@ 1 True Company.WebApplication1 + false - - - + + + - @@ -26,6 +26,7 @@ + diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/dotnetcli.host.json index c39487b527..324da5d6ae 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/dotnetcli.host.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/dotnetcli.host.json @@ -67,6 +67,10 @@ "NoHttps": { "longName": "no-https", "shortName": "" + }, + "RazorRuntimeCompilation": { + "longName": "razor-runtime-compilation", + "shortName": "rrc" } }, "usageExamples": [ diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json index 5a01244a34..679e237894 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json @@ -304,6 +304,12 @@ "defaultValue": "false", "description": "Whether to use LocalDB instead of SQLite. This option only applies if --auth Individual or --auth IndividualB2C is specified." }, + "RazorRuntimeCompilation": { + "type": "parameter", + "datatype": "bool", + "defaultValue": "false", + "description": "Determines if the project is configured to use Razor runtime compilation in Debug builds." + }, "Framework": { "type": "parameter", "description": "The target framework for the project.", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/vs-2017.3.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/vs-2017.3.host.json index 52ba934378..8ee1e7b877 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/vs-2017.3.host.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/vs-2017.3.host.json @@ -59,6 +59,15 @@ "useHttps": true } ], + "symbolInfo": [ + { + "id": "RazorRuntimeCompilation", + "name": { + "text": "Enable _Razor runtime compilation" + }, + "isVisible": "true" + } + ], "excludeLaunchSettings": false, "azureReplyUrlPortName": "HttpsPort", "minFullFrameworkVersion": "4.6.1", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Properties/launchSettings.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Properties/launchSettings.json index a65eda75e3..d40962c82d 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Properties/launchSettings.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Properties/launchSettings.json @@ -1,11 +1,11 @@ { "iisSettings": { - //#if (WindowsAuth) - "windowsAuthentication": true, - "anonymousAuthentication": false, - //#else - "windowsAuthentication": false, - "anonymousAuthentication": true, + //#if (WindowsAuth) + "windowsAuthentication": true, + "anonymousAuthentication": false, + //#else + "windowsAuthentication": false, + "anonymousAuthentication": true, //#endif "iisExpress": { "applicationUrl": "http://localhost:8080", @@ -21,7 +21,12 @@ "commandName": "IISExpress", "launchBrowser": true, "environmentVariables": { + //#if(RazorRuntimeCompilation) + "ASPNETCORE_ENVIRONMENT": "Development", + "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" + //#else "ASPNETCORE_ENVIRONMENT": "Development" + //#endif } }, "Company.WebApplication1": { @@ -33,7 +38,12 @@ "applicationUrl": "http://localhost:5000", //#endif "environmentVariables": { + //#if(RazorRuntimeCompilation) + "ASPNETCORE_ENVIRONMENT": "Development", + "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" + //#else "ASPNETCORE_ENVIRONMENT": "Development" + //#endif } } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/dotnetcli.host.json index 2473827568..5f4c4c45e5 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/dotnetcli.host.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/dotnetcli.host.json @@ -67,6 +67,10 @@ "NoHttps": { "longName": "no-https", "shortName": "" + }, + "RazorRuntimeCompilation": { + "longName": "razor-runtime-compilation", + "shortName": "rrc" } }, "usageExamples": [ diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json index d01fcbf4f0..8679ada1c6 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json @@ -294,6 +294,12 @@ "defaultValue": "false", "description": "Whether to use LocalDB instead of SQLite. This option only applies if --auth Individual or --auth IndividualB2C is specified." }, + "RazorRuntimeCompilation": { + "type": "parameter", + "datatype": "bool", + "defaultValue": "false", + "description": "Determines if the project is configured to use Razor runtime compilation in Debug builds." + }, "Framework": { "type": "parameter", "description": "The target framework for the project.", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/vs-2017.3.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/vs-2017.3.host.json index 35b22113a6..98149ec9ba 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/vs-2017.3.host.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/vs-2017.3.host.json @@ -59,6 +59,15 @@ "useHttps": true } ], + "symbolInfo": [ + { + "id": "RazorRuntimeCompilation", + "name": { + "text": "Enable _Razor runtime compilation" + }, + "isVisible": "true" + } + ], "excludeLaunchSettings": false, "azureReplyUrlPortName": "HttpsPort", "minFullFrameworkVersion": "4.6.1", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Properties/launchSettings.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Properties/launchSettings.json index a65eda75e3..d40962c82d 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Properties/launchSettings.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Properties/launchSettings.json @@ -1,11 +1,11 @@ { "iisSettings": { - //#if (WindowsAuth) - "windowsAuthentication": true, - "anonymousAuthentication": false, - //#else - "windowsAuthentication": false, - "anonymousAuthentication": true, + //#if (WindowsAuth) + "windowsAuthentication": true, + "anonymousAuthentication": false, + //#else + "windowsAuthentication": false, + "anonymousAuthentication": true, //#endif "iisExpress": { "applicationUrl": "http://localhost:8080", @@ -21,7 +21,12 @@ "commandName": "IISExpress", "launchBrowser": true, "environmentVariables": { + //#if(RazorRuntimeCompilation) + "ASPNETCORE_ENVIRONMENT": "Development", + "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" + //#else "ASPNETCORE_ENVIRONMENT": "Development" + //#endif } }, "Company.WebApplication1": { @@ -33,7 +38,12 @@ "applicationUrl": "http://localhost:5000", //#endif "environmentVariables": { + //#if(RazorRuntimeCompilation) + "ASPNETCORE_ENVIRONMENT": "Development", + "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" + //#else "ASPNETCORE_ENVIRONMENT": "Development" + //#endif } } } diff --git a/src/ProjectTemplates/test/MvcTemplateTest.cs b/src/ProjectTemplates/test/MvcTemplateTest.cs index af43914ed2..543ff779c0 100644 --- a/src/ProjectTemplates/test/MvcTemplateTest.cs +++ b/src/ProjectTemplates/test/MvcTemplateTest.cs @@ -212,5 +212,24 @@ namespace Templates.Test await aspNetProcess.AssertPagesOk(pages); } } + + [Fact] + public async Task MvcTemplate_RazorRuntimeCompilation_BuildsAndPublishes() + { + Project = await ProjectFactory.GetOrCreateProject("mvc_rc", Output); + + var createResult = await Project.RunDotNetNewAsync("mvc", args: new[] { "--razor-runtime-compilation" }); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + // Verify building in debug works + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + + // Publish builds in "release" configuration. Running publish should ensure we can compile in release and that we can publish without issues. + buildResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, buildResult)); + + Assert.False(Directory.Exists(Path.Combine(Project.TemplatePublishDir, "refs")), "The refs directory should not be published."); + } } } diff --git a/src/ProjectTemplates/test/RazorPagesTemplateTest.cs b/src/ProjectTemplates/test/RazorPagesTemplateTest.cs index 7cd41d56b2..3de64d6ea7 100644 --- a/src/ProjectTemplates/test/RazorPagesTemplateTest.cs +++ b/src/ProjectTemplates/test/RazorPagesTemplateTest.cs @@ -209,6 +209,29 @@ namespace Templates.Test } } + [Fact] + public async Task RazorPagesTemplate_RazorRuntimeCompilation_BuildsAndPublishes() + { + Project = await ProjectFactory.GetOrCreateProject("razorpages_rc", Output); + + var createResult = await Project.RunDotNetNewAsync("razor", args: new[] { "--razor-runtime-compilation" }); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + // Verify building in debug works + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + + // Publish builds in "release" configuration. Running publish should ensure we can compile in release and that we can publish without issues. + buildResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, buildResult)); + + Assert.False(Directory.Exists(Path.Combine(Project.TemplatePublishDir, "refs")), "The refs directory should not be published."); + + // Verify ref assemblies isn't published + var refsDirectory = Path.Combine(Project.TemplatePublishDir, "refs"); + Assert.False(Directory.Exists(refsDirectory), $"{refsDirectory} should not be in the publish output."); + } + private string ReadFile(string basePath, string path) {