From f7073d45c62aa1885328164fb1f4eea58a9c60e6 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 6 Mar 2023 18:16:07 -0600 Subject: [PATCH 1/2] Set InvariantGlobalization in api, webapi, grpc, and worker templates API server applications do not typically need culture aware behavior. A better default is to use invariant globalization mode for API apps. This allows for the globalization code to be trimmed away, making the final executable size smaller. It also reduces startup and memory consumption because ICU isn't loaded. This also allows the apps to run with consistent behavior on container images that don't include ICU, making the container image smaller as well. Fix #47029 --- src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in | 1 + .../Web.ProjectTemplates/GrpcService-CSharp.csproj.in | 1 + .../Web.ProjectTemplates/WebApi-CSharp.csproj.in | 1 + .../Web.ProjectTemplates/WebApi-FSharp.fsproj.in | 1 + .../Web.ProjectTemplates/Worker-CSharp.csproj.in | 1 + .../Web.ProjectTemplates/Worker-FSharp.fsproj.in | 1 + 6 files changed, 6 insertions(+) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in index c42865b4b667..ae3d10f13686 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in @@ -7,6 +7,7 @@ true Company.WebApplication1 false + true true diff --git a/src/ProjectTemplates/Web.ProjectTemplates/GrpcService-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/GrpcService-CSharp.csproj.in index 3554a4084796..3b003a21c4b3 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/GrpcService-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/GrpcService-CSharp.csproj.in @@ -4,6 +4,7 @@ ${DefaultNetCoreTargetFramework} enable enable + true true diff --git a/src/ProjectTemplates/Web.ProjectTemplates/WebApi-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/WebApi-CSharp.csproj.in index 5b949b47fba0..e79188f36d01 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/WebApi-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/WebApi-CSharp.csproj.in @@ -4,6 +4,7 @@ ${DefaultNetCoreTargetFramework} enable enable + true aspnet-Company.WebApplication1-53bc9b9d-9d6a-45d4-8429-2a2761773502 True Company.WebApplication1 diff --git a/src/ProjectTemplates/Web.ProjectTemplates/WebApi-FSharp.fsproj.in b/src/ProjectTemplates/Web.ProjectTemplates/WebApi-FSharp.fsproj.in index 8a9f8ed0e2e5..2065714d5cb2 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/WebApi-FSharp.fsproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/WebApi-FSharp.fsproj.in @@ -2,6 +2,7 @@ ${DefaultNetCoreTargetFramework} + true True Company.WebApplication1 diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Worker-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/Worker-CSharp.csproj.in index 19004ba1c8e9..85186fbef735 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/Worker-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/Worker-CSharp.csproj.in @@ -4,6 +4,7 @@ ${DefaultNetCoreTargetFramework} enable enable + true dotnet-Company.Application1-53bc9b9d-9d6a-45d4-8429-2a2761773502 True Company.Application1 diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Worker-FSharp.fsproj.in b/src/ProjectTemplates/Web.ProjectTemplates/Worker-FSharp.fsproj.in index c3905c0a7424..c106066e6eff 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/Worker-FSharp.fsproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/Worker-FSharp.fsproj.in @@ -3,6 +3,7 @@ ${DefaultNetCoreTargetFramework} dotnet-Company.Application1-53bc9b9d-9d6a-45d4-8429-2a2761773502 + true True Company.Application1 From daf3758c4f978f2aef9ab63b7a02e02507033466 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Thu, 9 Mar 2023 17:38:03 -0600 Subject: [PATCH 2/2] Add template tests to ensure InvariantGlobalization is set. --- src/ProjectTemplates/Shared/Project.cs | 10 ++++++++++ .../test/Templates.Tests/ApiTemplateTest.cs | 2 ++ .../test/Templates.Tests/GrpcTemplateTest.cs | 2 ++ .../test/Templates.Tests/WorkerTemplateTest.cs | 2 ++ 4 files changed, 16 insertions(+) diff --git a/src/ProjectTemplates/Shared/Project.cs b/src/ProjectTemplates/Shared/Project.cs index b9e9e7d60a91..58df70e03eba 100644 --- a/src/ProjectTemplates/Shared/Project.cs +++ b/src/ProjectTemplates/Shared/Project.cs @@ -352,6 +352,16 @@ public async Task VerifyLaunchSettings(string[] expectedLaunchProfileNames) } } + public async Task VerifyHasProperty(string propertyName, string expectedValue) + { + var projectFile = Directory.EnumerateFiles(TemplateOutputDir, "*proj").FirstOrDefault(); + + Assert.NotNull(projectFile); + + var projectFileContents = await File.ReadAllTextAsync(projectFile); + Assert.Contains($"<{propertyName}>{expectedValue}", projectFileContents); + } + public string ReadFile(string path) { AssertFileExists(path, shouldExist: true); diff --git a/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs b/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs index 319c7054207e..62bf4a7f3ad3 100644 --- a/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs +++ b/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs @@ -65,6 +65,8 @@ private async Task ApiTemplateCore(string languageOverride, string[] args = null : new[] { "http", "IIS Express" }; await project.VerifyLaunchSettings(expectedLaunchProfileNames); + await project.VerifyHasProperty("InvariantGlobalization", "true"); + // Avoid the F# compiler. See https://github.com/dotnet/aspnetcore/issues/14022 if (languageOverride != null) { diff --git a/src/ProjectTemplates/test/Templates.Tests/GrpcTemplateTest.cs b/src/ProjectTemplates/test/Templates.Tests/GrpcTemplateTest.cs index 7c4385d56e8c..e0d4fdecce8e 100644 --- a/src/ProjectTemplates/test/Templates.Tests/GrpcTemplateTest.cs +++ b/src/ProjectTemplates/test/Templates.Tests/GrpcTemplateTest.cs @@ -75,6 +75,8 @@ private async Task GrpcTemplateCore(string[] args = null) var expectedLaunchProfileNames = new[] { "http", "https" }; await project.VerifyLaunchSettings(expectedLaunchProfileNames); + await project.VerifyHasProperty("InvariantGlobalization", "true"); + await project.RunDotNetPublishAsync(); await project.RunDotNetBuildAsync(); diff --git a/src/ProjectTemplates/test/Templates.Tests/WorkerTemplateTest.cs b/src/ProjectTemplates/test/Templates.Tests/WorkerTemplateTest.cs index 4c1ad90756e4..46ca63e0c569 100644 --- a/src/ProjectTemplates/test/Templates.Tests/WorkerTemplateTest.cs +++ b/src/ProjectTemplates/test/Templates.Tests/WorkerTemplateTest.cs @@ -40,6 +40,8 @@ public async Task WorkerTemplateAsync(string language, string[] args) await project.RunDotNetNewAsync("worker", language: language, args: args); + await project.VerifyHasProperty("InvariantGlobalization", "true"); + await project.RunDotNetPublishAsync(); // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release