From 758f70520f0e12c49c83e20b10e07487bd9e8263 Mon Sep 17 00:00:00 2001 From: Chris R Date: Wed, 9 Jan 2019 15:40:30 -0800 Subject: [PATCH 1/7] React to WebHostBuilderFactory Sources move #6460 --- build/repo.props | 4 - eng/Dependencies.props | 1 + src/Hosting/Hosting.sln | 27 ---- .../src/Microsoft.AspNetCore.TestHost.csproj | 7 +- src/Hosting/TestHost/src/TestServer.cs | 2 +- .../TestHost/src/WebHostBuilderExtensions.cs | 16 +- .../TestHost/src/WebHostBuilderFactory.cs | 15 +- ...Hosting.WebHostBuilderFactory.Tests.csproj | 22 --- .../WebHostFactoryResolverTests.cs | 84 ----------- .../BuildWebHostInvalidSignature.csproj | 14 -- .../BuildWebHostInvalidSignature/Program.cs | 16 -- .../BuildWebHostInvalidSignature/Startup.cs | 19 --- .../BuildWebHostPatternTestSite.csproj | 14 -- .../BuildWebHostPatternTestSite/Program.cs | 16 -- .../BuildWebHostPatternTestSite/Startup.cs | 19 --- ...reateWebHostBuilderInvalidSignature.csproj | 14 -- .../Program.cs | 16 -- .../Startup.cs | 19 --- src/Mvc/Mvc.sln | 15 ++ .../Microsoft.AspNetCore.Mvc.Testing.csproj | 4 +- .../WebApplicationFactory.cs | 20 +++ ...soft.AspNetCore.Mvc.FunctionalTests.csproj | 1 + .../TestingInfrastructureTests.cs | 20 +++ src/Mvc/test/WebSites/BasicWebSite/Program.cs | 1 - src/Mvc/test/WebSites/BasicWebSite/Startup.cs | 2 + .../Controllers/TestingController.cs | 137 ++++++++++++++++++ .../GenericHostWebSite.csproj | 35 +++++ .../WebSites/GenericHostWebSite/Program.cs | 33 +++++ .../WebSites/GenericHostWebSite/Startup.cs | 58 ++++++++ .../WebSites/GenericHostWebSite/_bower.json | 14 ++ .../WebSites/GenericHostWebSite/_bower.readme | 7 + .../WebSites/GenericHostWebSite/_gruntfile.js | 20 +++ .../WebSites/GenericHostWebSite/_package.json | 10 ++ .../WebSites/GenericHostWebSite/readme.md | 4 + .../jquery.validate.unobtrusive.min.js | 5 + .../Directory.Build.props | 8 - .../FactoryResolutionResult.cs | 54 ------- .../FactoryResolutionResultKind.cs | 14 -- .../WebHostFactoryResolver.cs | 68 --------- 39 files changed, 403 insertions(+), 452 deletions(-) delete mode 100644 src/Hosting/test/WebHostBuilderFactory.Tests/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests.csproj delete mode 100644 src/Hosting/test/WebHostBuilderFactory.Tests/WebHostFactoryResolverTests.cs delete mode 100644 src/Hosting/test/testassets/BuildWebHostInvalidSignature/BuildWebHostInvalidSignature.csproj delete mode 100644 src/Hosting/test/testassets/BuildWebHostInvalidSignature/Program.cs delete mode 100644 src/Hosting/test/testassets/BuildWebHostInvalidSignature/Startup.cs delete mode 100644 src/Hosting/test/testassets/BuildWebHostPatternTestSite/BuildWebHostPatternTestSite.csproj delete mode 100644 src/Hosting/test/testassets/BuildWebHostPatternTestSite/Program.cs delete mode 100644 src/Hosting/test/testassets/BuildWebHostPatternTestSite/Startup.cs delete mode 100644 src/Hosting/test/testassets/CreateWebHostBuilderInvalidSignature/CreateWebHostBuilderInvalidSignature.csproj delete mode 100644 src/Hosting/test/testassets/CreateWebHostBuilderInvalidSignature/Program.cs delete mode 100644 src/Hosting/test/testassets/CreateWebHostBuilderInvalidSignature/Startup.cs create mode 100644 src/Mvc/test/WebSites/GenericHostWebSite/Controllers/TestingController.cs create mode 100644 src/Mvc/test/WebSites/GenericHostWebSite/GenericHostWebSite.csproj create mode 100644 src/Mvc/test/WebSites/GenericHostWebSite/Program.cs create mode 100644 src/Mvc/test/WebSites/GenericHostWebSite/Startup.cs create mode 100644 src/Mvc/test/WebSites/GenericHostWebSite/_bower.json create mode 100644 src/Mvc/test/WebSites/GenericHostWebSite/_bower.readme create mode 100644 src/Mvc/test/WebSites/GenericHostWebSite/_gruntfile.js create mode 100644 src/Mvc/test/WebSites/GenericHostWebSite/_package.json create mode 100644 src/Mvc/test/WebSites/GenericHostWebSite/readme.md create mode 100644 src/Mvc/test/WebSites/GenericHostWebSite/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js delete mode 100644 src/Shared/Hosting.WebHostBuilderFactory/Directory.Build.props delete mode 100644 src/Shared/Hosting.WebHostBuilderFactory/FactoryResolutionResult.cs delete mode 100644 src/Shared/Hosting.WebHostBuilderFactory/FactoryResolutionResultKind.cs delete mode 100644 src/Shared/Hosting.WebHostBuilderFactory/WebHostFactoryResolver.cs diff --git a/build/repo.props b/build/repo.props index 3482b02d5ae2..f50b7d4f0364 100644 --- a/build/repo.props +++ b/build/repo.props @@ -34,10 +34,6 @@ true - - - - diff --git a/eng/Dependencies.props b/eng/Dependencies.props index a1d4f65b4823..b8f7e028efa9 100644 --- a/eng/Dependencies.props +++ b/eng/Dependencies.props @@ -65,6 +65,7 @@ and are generated based on the last package release. + diff --git a/src/Hosting/Hosting.sln b/src/Hosting/Hosting.sln index 7f1103247a3c..0fad5fbf1623 100644 --- a/src/Hosting/Hosting.sln +++ b/src/Hosting/Hosting.sln @@ -29,16 +29,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Hostin EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", "{31587D24-F6B5-4A47-A962-47CA7FEA79D0}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildWebHostInvalidSignature", "test\testassets\BuildWebHostInvalidSignature\BuildWebHostInvalidSignature.csproj", "{BF146375-AA6C-43F3-BF0A-DCA551892DF8}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Hosting.FunctionalTests", "test\FunctionalTests\Microsoft.AspNetCore.Hosting.FunctionalTests.csproj", "{D6EC0A3E-384A-4EE9-8068-21E1848BBB11}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests", "test\WebHostBuilderFactory.Tests\Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests.csproj", "{4AB4D911-7741-4F3E-982E-7945C6FC36C4}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildWebHostPatternTestSite", "test\testassets\BuildWebHostPatternTestSite\BuildWebHostPatternTestSite.csproj", "{953E1E06-F39F-45E7-840D-FA8DE1E01740}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CreateWebHostBuilderInvalidSignature", "test\testassets\CreateWebHostBuilderInvalidSignature\CreateWebHostBuilderInvalidSignature.csproj", "{BE562963-37E1-410F-8751-A3044458B861}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IStartupInjectionAssemblyName", "test\testassets\IStartupInjectionAssemblyName\IStartupInjectionAssemblyName.csproj", "{F032B4F6-2F03-4885-AB03-CA81038808A6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Hosting.TestSites", "test\testassets\Microsoft.AspNetCore.Hosting.TestSites\Microsoft.AspNetCore.Hosting.TestSites.csproj", "{9CA19BE4-DC10-4690-9142-61BD007B6D80}" @@ -95,26 +87,10 @@ Global {CCD5D010-7E06-4209-ADD5-3B010A41DCF1}.Debug|Any CPU.Build.0 = Debug|Any CPU {CCD5D010-7E06-4209-ADD5-3B010A41DCF1}.Release|Any CPU.ActiveCfg = Release|Any CPU {CCD5D010-7E06-4209-ADD5-3B010A41DCF1}.Release|Any CPU.Build.0 = Release|Any CPU - {BF146375-AA6C-43F3-BF0A-DCA551892DF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BF146375-AA6C-43F3-BF0A-DCA551892DF8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BF146375-AA6C-43F3-BF0A-DCA551892DF8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BF146375-AA6C-43F3-BF0A-DCA551892DF8}.Release|Any CPU.Build.0 = Release|Any CPU {D6EC0A3E-384A-4EE9-8068-21E1848BBB11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D6EC0A3E-384A-4EE9-8068-21E1848BBB11}.Debug|Any CPU.Build.0 = Debug|Any CPU {D6EC0A3E-384A-4EE9-8068-21E1848BBB11}.Release|Any CPU.ActiveCfg = Release|Any CPU {D6EC0A3E-384A-4EE9-8068-21E1848BBB11}.Release|Any CPU.Build.0 = Release|Any CPU - {4AB4D911-7741-4F3E-982E-7945C6FC36C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4AB4D911-7741-4F3E-982E-7945C6FC36C4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4AB4D911-7741-4F3E-982E-7945C6FC36C4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4AB4D911-7741-4F3E-982E-7945C6FC36C4}.Release|Any CPU.Build.0 = Release|Any CPU - {953E1E06-F39F-45E7-840D-FA8DE1E01740}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {953E1E06-F39F-45E7-840D-FA8DE1E01740}.Debug|Any CPU.Build.0 = Debug|Any CPU - {953E1E06-F39F-45E7-840D-FA8DE1E01740}.Release|Any CPU.ActiveCfg = Release|Any CPU - {953E1E06-F39F-45E7-840D-FA8DE1E01740}.Release|Any CPU.Build.0 = Release|Any CPU - {BE562963-37E1-410F-8751-A3044458B861}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BE562963-37E1-410F-8751-A3044458B861}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BE562963-37E1-410F-8751-A3044458B861}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BE562963-37E1-410F-8751-A3044458B861}.Release|Any CPU.Build.0 = Release|Any CPU {F032B4F6-2F03-4885-AB03-CA81038808A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F032B4F6-2F03-4885-AB03-CA81038808A6}.Debug|Any CPU.Build.0 = Debug|Any CPU {F032B4F6-2F03-4885-AB03-CA81038808A6}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -134,9 +110,6 @@ Global GlobalSection(NestedProjects) = preSolution {7351DDBC-71DF-4C40-A364-981710B80E29} = {3E9635DD-53A9-4098-B6F6-E5C3C8F7C600} {3C3F4D2D-6676-4A0B-895D-348E7DD4152E} = {3E9635DD-53A9-4098-B6F6-E5C3C8F7C600} - {BF146375-AA6C-43F3-BF0A-DCA551892DF8} = {31587D24-F6B5-4A47-A962-47CA7FEA79D0} - {953E1E06-F39F-45E7-840D-FA8DE1E01740} = {31587D24-F6B5-4A47-A962-47CA7FEA79D0} - {BE562963-37E1-410F-8751-A3044458B861} = {31587D24-F6B5-4A47-A962-47CA7FEA79D0} {F032B4F6-2F03-4885-AB03-CA81038808A6} = {31587D24-F6B5-4A47-A962-47CA7FEA79D0} {9CA19BE4-DC10-4690-9142-61BD007B6D80} = {31587D24-F6B5-4A47-A962-47CA7FEA79D0} {570D1047-A109-4209-9258-9BA7C8BDC9AA} = {31587D24-F6B5-4A47-A962-47CA7FEA79D0} diff --git a/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj b/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj index f309bf0eea2c..b6744c1360b5 100644 --- a/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj +++ b/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj @@ -1,4 +1,4 @@ - + ASP.NET Core web server for writing and running tests. @@ -9,12 +9,9 @@ true - - - - + diff --git a/src/Hosting/TestHost/src/TestServer.cs b/src/Hosting/TestHost/src/TestServer.cs index 40a3e63f0569..6c45c0b21b43 100644 --- a/src/Hosting/TestHost/src/TestServer.cs +++ b/src/Hosting/TestHost/src/TestServer.cs @@ -146,7 +146,7 @@ public void Dispose() if (!_disposed) { _disposed = true; - _hostInstance.Dispose(); + _hostInstance?.Dispose(); } } diff --git a/src/Hosting/TestHost/src/WebHostBuilderExtensions.cs b/src/Hosting/TestHost/src/WebHostBuilderExtensions.cs index 308ac86cd43b..41b7c31dba2c 100644 --- a/src/Hosting/TestHost/src/WebHostBuilderExtensions.cs +++ b/src/Hosting/TestHost/src/WebHostBuilderExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// 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 System; @@ -33,9 +33,17 @@ public static IWebHostBuilder ConfigureTestServices(this IWebHostBuilder webHost throw new ArgumentNullException(nameof(servicesConfiguration)); } - webHostBuilder.ConfigureServices( - s => s.AddSingleton( - new ConfigureTestServicesStartupConfigureServicesFilter(servicesConfiguration))); + if (webHostBuilder.GetType().Name.Equals("GenericWebHostBuilder")) + { + // Generic host doesn't need to do anything special here since there's only one container. + webHostBuilder.ConfigureServices(servicesConfiguration); + } + else + { + webHostBuilder.ConfigureServices( + s => s.AddSingleton( + new ConfigureTestServicesStartupConfigureServicesFilter(servicesConfiguration))); + } return webHostBuilder; } diff --git a/src/Hosting/TestHost/src/WebHostBuilderFactory.cs b/src/Hosting/TestHost/src/WebHostBuilderFactory.cs index 3a0b0a552e9b..86930ce8d5de 100644 --- a/src/Hosting/TestHost/src/WebHostBuilderFactory.cs +++ b/src/Hosting/TestHost/src/WebHostBuilderFactory.cs @@ -1,23 +1,18 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// 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 System.Reflection; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Hosting.WebHostBuilderFactory; +using Microsoft.Extensions.Hosting; namespace Microsoft.AspNetCore.TestHost { public static class WebHostBuilderFactory { - public static IWebHostBuilder CreateFromAssemblyEntryPoint(Assembly assembly, string [] args) + public static IWebHostBuilder CreateFromAssemblyEntryPoint(Assembly assembly, string[] args) { - var result = WebHostFactoryResolver.ResolveWebHostBuilderFactory(assembly); - if (result.ResultKind != FactoryResolutionResultKind.Success) - { - return null; - } - - return result.WebHostBuilderFactory(args); + var factory = HostFactoryResolver.ResolveWebHostBuilderFactory(assembly); + return factory?.Invoke(args); } public static IWebHostBuilder CreateFromTypesAssemblyEntryPoint(string[] args) => diff --git a/src/Hosting/test/WebHostBuilderFactory.Tests/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests.csproj b/src/Hosting/test/WebHostBuilderFactory.Tests/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests.csproj deleted file mode 100644 index 359607677ba0..000000000000 --- a/src/Hosting/test/WebHostBuilderFactory.Tests/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - netcoreapp3.0 - - - - - - - - - - - - - - - - - - diff --git a/src/Hosting/test/WebHostBuilderFactory.Tests/WebHostFactoryResolverTests.cs b/src/Hosting/test/WebHostBuilderFactory.Tests/WebHostFactoryResolverTests.cs deleted file mode 100644 index f2732f75c48a..000000000000 --- a/src/Hosting/test/WebHostBuilderFactory.Tests/WebHostFactoryResolverTests.cs +++ /dev/null @@ -1,84 +0,0 @@ -// 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 System; -using Xunit; - -namespace Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests -{ - public class WebHostFactoryResolverTests - { - [Fact] - public void CanFindWebHostBuilder_CreateWebHostBuilderPattern() - { - // Arrange & Act - var resolverResult = WebHostFactoryResolver.ResolveWebHostBuilderFactory(typeof(IStartupInjectionAssemblyName.Startup).Assembly); - - // Assert - Assert.Equal(FactoryResolutionResultKind.Success, resolverResult.ResultKind); - Assert.NotNull(resolverResult.WebHostBuilderFactory); - Assert.NotNull(resolverResult.WebHostFactory); - Assert.IsAssignableFrom(resolverResult.WebHostBuilderFactory(Array.Empty())); - } - - [Fact] - public void CanFindWebHost_CreateWebHostBuilderPattern() - { - // Arrange & Act - var resolverResult = WebHostFactoryResolver.ResolveWebHostFactory(typeof(IStartupInjectionAssemblyName.Startup).Assembly); - - // Assert - Assert.Equal(FactoryResolutionResultKind.Success, resolverResult.ResultKind); - Assert.NotNull(resolverResult.WebHostBuilderFactory); - Assert.NotNull(resolverResult.WebHostFactory); - } - - [Fact] - public void CanNotFindWebHostBuilder_BuildWebHostPattern() - { - // Arrange & Act - var resolverResult = WebHostFactoryResolver.ResolveWebHostBuilderFactory(typeof(BuildWebHostPatternTestSite.Startup).Assembly); - - // Assert - Assert.Equal(FactoryResolutionResultKind.NoCreateWebHostBuilder, resolverResult.ResultKind); - Assert.Null(resolverResult.WebHostBuilderFactory); - Assert.Null(resolverResult.WebHostFactory); - } - - [Fact] - public void CanNotFindWebHostBuilder_CreateWebHostBuilderIncorrectSignature() - { - // Arrange & Act - var resolverResult = WebHostFactoryResolver.ResolveWebHostBuilderFactory(typeof(CreateWebHostBuilderInvalidSignature.Startup).Assembly); - - // Assert - Assert.Equal(FactoryResolutionResultKind.NoCreateWebHostBuilder, resolverResult.ResultKind); - Assert.Null(resolverResult.WebHostBuilderFactory); - Assert.Null(resolverResult.WebHostFactory); - } - - [Fact] - public void CanNotFindWebHost_BuildWebHostIncorrectSignature() - { - // Arrange & Act - var resolverResult = WebHostFactoryResolver.ResolveWebHostFactory(typeof(BuildWebHostInvalidSignature.Startup).Assembly); - - // Assert - Assert.Equal(FactoryResolutionResultKind.NoBuildWebHost, resolverResult.ResultKind); - Assert.Null(resolverResult.WebHostBuilderFactory); - Assert.Null(resolverResult.WebHostFactory); - } - - [Fact] - public void CanFindWebHost_BuildWebHostPattern() - { - // Arrange & Act - var resolverResult = WebHostFactoryResolver.ResolveWebHostFactory(typeof(BuildWebHostPatternTestSite.Startup).Assembly); - - // Assert - Assert.Equal(FactoryResolutionResultKind.Success, resolverResult.ResultKind); - Assert.Null(resolverResult.WebHostBuilderFactory); - Assert.NotNull(resolverResult.WebHostFactory); - } - } -} diff --git a/src/Hosting/test/testassets/BuildWebHostInvalidSignature/BuildWebHostInvalidSignature.csproj b/src/Hosting/test/testassets/BuildWebHostInvalidSignature/BuildWebHostInvalidSignature.csproj deleted file mode 100644 index 3ea37b679b61..000000000000 --- a/src/Hosting/test/testassets/BuildWebHostInvalidSignature/BuildWebHostInvalidSignature.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - netcoreapp3.0 - Exe - - - - - - - - - diff --git a/src/Hosting/test/testassets/BuildWebHostInvalidSignature/Program.cs b/src/Hosting/test/testassets/BuildWebHostInvalidSignature/Program.cs deleted file mode 100644 index b25cb703ad09..000000000000 --- a/src/Hosting/test/testassets/BuildWebHostInvalidSignature/Program.cs +++ /dev/null @@ -1,16 +0,0 @@ -// 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; - -namespace BuildWebHostInvalidSignature -{ - class Program - { - static void Main(string[] args) - { - } - - public static IWebHost BuildWebHost() => null; - } -} diff --git a/src/Hosting/test/testassets/BuildWebHostInvalidSignature/Startup.cs b/src/Hosting/test/testassets/BuildWebHostInvalidSignature/Startup.cs deleted file mode 100644 index 0b52bc36b875..000000000000 --- a/src/Hosting/test/testassets/BuildWebHostInvalidSignature/Startup.cs +++ /dev/null @@ -1,19 +0,0 @@ -// 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.Builder; -using Microsoft.Extensions.DependencyInjection; - -namespace BuildWebHostInvalidSignature -{ - public class Startup - { - public void ConfigureServices(IServiceCollection services) - { - } - - public void Configure(IApplicationBuilder builder) - { - } - } -} diff --git a/src/Hosting/test/testassets/BuildWebHostPatternTestSite/BuildWebHostPatternTestSite.csproj b/src/Hosting/test/testassets/BuildWebHostPatternTestSite/BuildWebHostPatternTestSite.csproj deleted file mode 100644 index 3ea37b679b61..000000000000 --- a/src/Hosting/test/testassets/BuildWebHostPatternTestSite/BuildWebHostPatternTestSite.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - netcoreapp3.0 - Exe - - - - - - - - - diff --git a/src/Hosting/test/testassets/BuildWebHostPatternTestSite/Program.cs b/src/Hosting/test/testassets/BuildWebHostPatternTestSite/Program.cs deleted file mode 100644 index a5a20508b9e0..000000000000 --- a/src/Hosting/test/testassets/BuildWebHostPatternTestSite/Program.cs +++ /dev/null @@ -1,16 +0,0 @@ -// 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; - -namespace BuildWebHostPatternTestSite -{ - class Program - { - static void Main(string[] args) - { - } - - public static IWebHost BuildWebHost(string[] args) => null; - } -} diff --git a/src/Hosting/test/testassets/BuildWebHostPatternTestSite/Startup.cs b/src/Hosting/test/testassets/BuildWebHostPatternTestSite/Startup.cs deleted file mode 100644 index 10ecf07a99af..000000000000 --- a/src/Hosting/test/testassets/BuildWebHostPatternTestSite/Startup.cs +++ /dev/null @@ -1,19 +0,0 @@ -// 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.Builder; -using Microsoft.Extensions.DependencyInjection; - -namespace BuildWebHostPatternTestSite -{ - public class Startup - { - public void ConfigureServices(IServiceCollection services) - { - } - - public void Configure(IApplicationBuilder builder) - { - } - } -} diff --git a/src/Hosting/test/testassets/CreateWebHostBuilderInvalidSignature/CreateWebHostBuilderInvalidSignature.csproj b/src/Hosting/test/testassets/CreateWebHostBuilderInvalidSignature/CreateWebHostBuilderInvalidSignature.csproj deleted file mode 100644 index 3ea37b679b61..000000000000 --- a/src/Hosting/test/testassets/CreateWebHostBuilderInvalidSignature/CreateWebHostBuilderInvalidSignature.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - netcoreapp3.0 - Exe - - - - - - - - - diff --git a/src/Hosting/test/testassets/CreateWebHostBuilderInvalidSignature/Program.cs b/src/Hosting/test/testassets/CreateWebHostBuilderInvalidSignature/Program.cs deleted file mode 100644 index 9322836fe0a3..000000000000 --- a/src/Hosting/test/testassets/CreateWebHostBuilderInvalidSignature/Program.cs +++ /dev/null @@ -1,16 +0,0 @@ -// 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; - -namespace CreateWebHostBuilderInvalidSignature -{ - class Program - { - static void Main(string[] args) - { - } - - public static IWebHostBuilder CreateWebHostBuilder() => null; - } -} diff --git a/src/Hosting/test/testassets/CreateWebHostBuilderInvalidSignature/Startup.cs b/src/Hosting/test/testassets/CreateWebHostBuilderInvalidSignature/Startup.cs deleted file mode 100644 index 2655a7e9374b..000000000000 --- a/src/Hosting/test/testassets/CreateWebHostBuilderInvalidSignature/Startup.cs +++ /dev/null @@ -1,19 +0,0 @@ -// 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.Builder; -using Microsoft.Extensions.DependencyInjection; - -namespace CreateWebHostBuilderInvalidSignature -{ - public class Startup - { - public void ConfigureServices(IServiceCollection services) - { - } - - public void Configure(IApplicationBuilder builder) - { - } - } -} diff --git a/src/Mvc/Mvc.sln b/src/Mvc/Mvc.sln index 1dfdb979112a..316098c92764 100644 --- a/src/Mvc/Mvc.sln +++ b/src/Mvc/Mvc.sln @@ -268,6 +268,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Respon EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IISIntegration", "..\Servers\IIS\IISIntegration\src\Microsoft.AspNetCore.Server.IISIntegration.csproj", "{35AE5599-AD99-4198-AC91-C599459E9023}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GenericHostWebSite", "test\WebSites\GenericHostWebSite\GenericHostWebSite.csproj", "{D9BE3E50-5CE8-4D8D-BA19-AA219D009752}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1562,6 +1564,18 @@ Global {35AE5599-AD99-4198-AC91-C599459E9023}.Release|Mixed Platforms.Build.0 = Release|Any CPU {35AE5599-AD99-4198-AC91-C599459E9023}.Release|x86.ActiveCfg = Release|Any CPU {35AE5599-AD99-4198-AC91-C599459E9023}.Release|x86.Build.0 = Release|Any CPU + {D9BE3E50-5CE8-4D8D-BA19-AA219D009752}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D9BE3E50-5CE8-4D8D-BA19-AA219D009752}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D9BE3E50-5CE8-4D8D-BA19-AA219D009752}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {D9BE3E50-5CE8-4D8D-BA19-AA219D009752}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {D9BE3E50-5CE8-4D8D-BA19-AA219D009752}.Debug|x86.ActiveCfg = Debug|Any CPU + {D9BE3E50-5CE8-4D8D-BA19-AA219D009752}.Debug|x86.Build.0 = Debug|Any CPU + {D9BE3E50-5CE8-4D8D-BA19-AA219D009752}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D9BE3E50-5CE8-4D8D-BA19-AA219D009752}.Release|Any CPU.Build.0 = Release|Any CPU + {D9BE3E50-5CE8-4D8D-BA19-AA219D009752}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {D9BE3E50-5CE8-4D8D-BA19-AA219D009752}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {D9BE3E50-5CE8-4D8D-BA19-AA219D009752}.Release|x86.ActiveCfg = Release|Any CPU + {D9BE3E50-5CE8-4D8D-BA19-AA219D009752}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1678,6 +1692,7 @@ Global {C75C6E51-4FFD-4902-8739-9109E51875B4} = {9328599D-A7AF-43BC-BE08-7503DF9B8CE6} {11D8DEBD-2E84-4EF2-8039-4B4BAC58F189} = {9328599D-A7AF-43BC-BE08-7503DF9B8CE6} {35AE5599-AD99-4198-AC91-C599459E9023} = {9328599D-A7AF-43BC-BE08-7503DF9B8CE6} + {D9BE3E50-5CE8-4D8D-BA19-AA219D009752} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {63D344F6-F86D-40E6-85B9-0AABBE338C4A} diff --git a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Microsoft.AspNetCore.Mvc.Testing.csproj b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Microsoft.AspNetCore.Mvc.Testing.csproj index 5ea627fc004e..da9de4204560 100644 --- a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Microsoft.AspNetCore.Mvc.Testing.csproj +++ b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Microsoft.AspNetCore.Mvc.Testing.csproj @@ -11,10 +11,8 @@ - - - + diff --git a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs index 8356180bd93e..bf2b7e411cb9 100644 --- a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs +++ b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs @@ -8,8 +8,11 @@ using System.Net.Http; using System.Reflection; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyModel; +using Microsoft.Extensions.Hosting; namespace Microsoft.AspNetCore.Mvc.Testing { @@ -22,6 +25,7 @@ public class WebApplicationFactory : IDisposable where TEntryPoint { private bool _disposed; private TestServer _server; + private IHost _host; private Action _configuration; private IList _clients = new List(); private List> _derivedFactories = @@ -119,6 +123,21 @@ private void EnsureServer() EnsureDepsFile(); + var hostBuilder = HostFactoryResolver.ResolveHostBuilderFactory(typeof(TEntryPoint).Assembly)?.Invoke(Array.Empty()); + if (hostBuilder != null) + { + hostBuilder.ConfigureWebHost(webHostBuilder => + { + webHostBuilder.UseEnvironment("Development"); + SetContentRoot(webHostBuilder); + _configuration(webHostBuilder); + webHostBuilder.UseTestServer(); + }); + _host = hostBuilder.Build(); + _host.Start(); + _server = (TestServer)_host.Services.GetRequiredService(); + return; + } var builder = CreateWebHostBuilder(); SetContentRoot(builder); @@ -425,6 +444,7 @@ protected virtual void Dispose(bool disposing) } _server?.Dispose(); + _host?.Dispose(); } _disposed = true; diff --git a/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/Microsoft.AspNetCore.Mvc.FunctionalTests.csproj b/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/Microsoft.AspNetCore.Mvc.FunctionalTests.csproj index 0318f58efb9a..b4e4e33ab005 100644 --- a/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/Microsoft.AspNetCore.Mvc.FunctionalTests.csproj +++ b/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/Microsoft.AspNetCore.Mvc.FunctionalTests.csproj @@ -38,6 +38,7 @@ + diff --git a/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/TestingInfrastructureTests.cs b/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/TestingInfrastructureTests.cs index 341fce0f54d9..4efe20247008 100644 --- a/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/TestingInfrastructureTests.cs +++ b/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/TestingInfrastructureTests.cs @@ -119,6 +119,18 @@ public async Task TestingInfrastructure_PutWithoutBodyFollowsRedirects() Assert.Equal(5, await response.Content.ReadAsAsync()); } + [Fact] + public async Task TestingInfrastructure_WorksWithGenericHost() + { + var factory = new WebApplicationFactory() + .WithWebHostBuilder(builder => + builder.ConfigureTestServices(s => s.AddSingleton())); + + var response = await factory.CreateClient().GetStringAsync("Testing/Builder"); + + Assert.Equal("GenericTest", response); + } + private class OverridenService : TestService { public OverridenService() @@ -127,6 +139,14 @@ public OverridenService() } } + private class OverridenGenericService : GenericHostWebSite.TestGenericService + { + public OverridenGenericService() + { + Message = "GenericTest"; + } + } + private class TestHandler : DelegatingHandler { public TestHandler() diff --git a/src/Mvc/test/WebSites/BasicWebSite/Program.cs b/src/Mvc/test/WebSites/BasicWebSite/Program.cs index 2de761fdc59a..11818853eb3b 100644 --- a/src/Mvc/test/WebSites/BasicWebSite/Program.cs +++ b/src/Mvc/test/WebSites/BasicWebSite/Program.cs @@ -17,7 +17,6 @@ public static IWebHostBuilder CreateWebHostBuilder(string[] args) => new WebHostBuilder() .UseContentRoot(Directory.GetCurrentDirectory()) .UseStartup() - .ConfigureServices(s => s.AddSingleton(new TestService { Message = "true" })) .UseKestrel() .UseIISIntegration(); } diff --git a/src/Mvc/test/WebSites/BasicWebSite/Startup.cs b/src/Mvc/test/WebSites/BasicWebSite/Startup.cs index 930837a49f29..8147a6b7749f 100644 --- a/src/Mvc/test/WebSites/BasicWebSite/Startup.cs +++ b/src/Mvc/test/WebSites/BasicWebSite/Startup.cs @@ -16,6 +16,8 @@ public class Startup // Set up application services public void ConfigureServices(IServiceCollection services) { + services.AddSingleton(new TestService { Message = "true" }); + services.AddAuthentication() .AddScheme("Api", _ => { }); services.AddTransient(); diff --git a/src/Mvc/test/WebSites/GenericHostWebSite/Controllers/TestingController.cs b/src/Mvc/test/WebSites/GenericHostWebSite/Controllers/TestingController.cs new file mode 100644 index 000000000000..cf254f717b22 --- /dev/null +++ b/src/Mvc/test/WebSites/GenericHostWebSite/Controllers/TestingController.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace GenericHostWebSite.Controllers +{ + public class TestingController : Controller + { + public TestingController(TestGenericService service) + { + Service = service; + } + + public TestGenericService Service { get; } + + [HttpGet("Testing/Builder")] + public string Get() => Service.Message; + + [HttpPost("Testing/RedirectHandler/{value}")] + public IActionResult RedirectHandler( + [FromRoute]int value, + [FromBody] Number number, + [FromHeader(Name = "X-Pass-Thru")] string passThruValue) + { + Response.Headers.Add("X-Pass-Thru", passThruValue); + if (value < number.Value) + { + return RedirectToActionPreserveMethod( + nameof(RedirectHandler), + "Testing", + new { value = value + 1 }); + } + + return Ok(new RedirectHandlerResponse { Url = value, Body = number.Value }); + } + + [HttpGet("Testing/RedirectHandler/Headers")] + public IActionResult RedirectHandlerHeaders() + { + if (!Request.Headers.TryGetValue("X-Added-Header", out var value)) + { + return Content("No header present"); + } + else + { + return RedirectToAction(nameof(RedirectHandlerHeadersRedirect)); + } + } + + [HttpGet("Testing/RedirectHandler/Headers/Redirect")] + public IActionResult RedirectHandlerHeadersRedirect() + { + if (Request.Headers.TryGetValue("X-Added-Header", out var value)) + { + return Content("true"); + } + else + { + return Content("false"); + } + } + + [HttpGet("Testing/AntiforgerySimulator/{value}")] + public IActionResult AntiforgerySimulator([FromRoute]int value) + { + Response.Cookies.Append( + "AntiforgerySimulator", + $"Cookie-{value.ToString(CultureInfo.InvariantCulture)}"); + + return Ok(); + } + + + [HttpPost("Testing/PostRedirectGet/Post/{value}")] + public IActionResult PostRedirectGetPost([FromRoute]int value) + { + var compareValue = $"Cookie-{value.ToString(CultureInfo.InvariantCulture)}"; + if (!Request.Cookies.ContainsKey("AntiforgerySimulator")) + { + return BadRequest("Missing AntiforgerySimulator cookie"); + } + + if (!string.Equals(compareValue, Request.Cookies["AntiforgerySimulator"])) + { + return BadRequest("Values don't match"); + } + + TempData["Value"] = value + 1; + Response.Cookies.Append("Message", $"Value-{(value + 1).ToString(CultureInfo.InvariantCulture)}"); + + return RedirectToAction(nameof(PostRedirectGetGet)); + } + + [HttpGet("Testing/PostRedirectGet/Get/{value}")] + public IActionResult PostRedirectGetGet([FromRoute]int value) + { + return Ok(new PostRedirectGetGetResponse + { + TempDataValue = (int)TempData["Value"], + CookieValue = Request.Cookies["Message"] + }); + } + + [HttpPut("Testing/Put/{value}")] + public IActionResult PutNoBody([FromRoute]int value) + { + if (value < 5) + { + return RedirectToActionPermanentPreserveMethod(nameof(PutNoBody), "Testing", new { value = value + 1 }); + } + else + { + return Ok(value); + } + } + } + + public class PostRedirectGetGetResponse + { + public int TempDataValue { get; set; } + public string CookieValue { get; set; } + } + + public class RedirectHandlerResponse + { + public int Url { get; set; } + public int Body { get; set; } + } + + public class Number + { + public int Value { get; set; } + } +} diff --git a/src/Mvc/test/WebSites/GenericHostWebSite/GenericHostWebSite.csproj b/src/Mvc/test/WebSites/GenericHostWebSite/GenericHostWebSite.csproj new file mode 100644 index 000000000000..68cc40b8ae9b --- /dev/null +++ b/src/Mvc/test/WebSites/GenericHostWebSite/GenericHostWebSite.csproj @@ -0,0 +1,35 @@ + + + + netcoreapp3.0 + true + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Mvc/test/WebSites/GenericHostWebSite/Program.cs b/src/Mvc/test/WebSites/GenericHostWebSite/Program.cs new file mode 100644 index 000000000000..81389a14946d --- /dev/null +++ b/src/Mvc/test/WebSites/GenericHostWebSite/Program.cs @@ -0,0 +1,33 @@ +// 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 System.IO; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace GenericHostWebSite +{ + public class Program + { + public static void Main(string[] args) => CreateHostBuilder(args).Build().Run(); + + // Do not change. This is the pattern our test infrastructure uses to initialize a IHostBuilder from + // a users app. + public static IHostBuilder CreateHostBuilder(string[] args) => + new HostBuilder() + .UseContentRoot(Directory.GetCurrentDirectory()) + .ConfigureWebHost(webHostBuilder => + { + webHostBuilder + .UseStartup() + .UseKestrel() + .UseIISIntegration(); + }); + } + + public class TestGenericService + { + public string Message { get; set; } + } +} diff --git a/src/Mvc/test/WebSites/GenericHostWebSite/Startup.cs b/src/Mvc/test/WebSites/GenericHostWebSite/Startup.cs new file mode 100644 index 000000000000..7250470c0796 --- /dev/null +++ b/src/Mvc/test/WebSites/GenericHostWebSite/Startup.cs @@ -0,0 +1,58 @@ +// 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.Authentication; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Infrastructure; +using Microsoft.Extensions.DependencyInjection; + +namespace GenericHostWebSite +{ + public class Startup + { + // Set up application services + public void ConfigureServices(IServiceCollection services) + { + services.AddSingleton(new TestGenericService { Message = "true" }); + + services + .AddMvc(options => + { + // Remove when all URL generation tests are passing - https://github.com/aspnet/Routing/issues/590 + options.EnableEndpointRouting = false; + }) + .SetCompatibilityVersion(CompatibilityVersion.Latest) + .AddNewtonsoftJson() + .AddXmlDataContractSerializerFormatters(); + + services.AddLogging(); + services.AddHttpContextAccessor(); + services.AddScoped(); + services.AddSingleton(); + } + + public void Configure(IApplicationBuilder app) + { + app.UseDeveloperExceptionPage(); + + app.UseStaticFiles(); + + // Add MVC to the request pipeline + app.UseMvc(routes => + { + routes.MapRoute( + "areaRoute", + "{area:exists}/{controller}/{action}", + new { controller = "Home", action = "Index" }); + + routes.MapRoute("ActionAsMethod", "{controller}/{action}", + defaults: new { controller = "Home", action = "Index" }); + + routes.MapRoute("PageRoute", "{controller}/{action}/{page}"); + }); + } + } +} diff --git a/src/Mvc/test/WebSites/GenericHostWebSite/_bower.json b/src/Mvc/test/WebSites/GenericHostWebSite/_bower.json new file mode 100644 index 000000000000..984cfb20bffe --- /dev/null +++ b/src/Mvc/test/WebSites/GenericHostWebSite/_bower.json @@ -0,0 +1,14 @@ +{ + "name": "GenericHostWebSite", + "description": "Web site demonstrating various validations.", + "private": true, + "dependencies": { + "jquery-validation-unobtrusive": "3.2.6" + }, + "exportsOverride": { + "jquery-validation-unobtrusive": { + "": "jquery.validate.unobtrusive.min.js" + }, + "*": { } + } +} \ No newline at end of file diff --git a/src/Mvc/test/WebSites/GenericHostWebSite/_bower.readme b/src/Mvc/test/WebSites/GenericHostWebSite/_bower.readme new file mode 100644 index 000000000000..a4fdaba27e76 --- /dev/null +++ b/src/Mvc/test/WebSites/GenericHostWebSite/_bower.readme @@ -0,0 +1,7 @@ +To recreate minified JavaScript file, + +1. Update jquery-validation-unobtrusive version in _bower.json if necessary. +2. Rename or copy _bower.json to bower.json, _gruntfile.js to gruntfile.js, and _package.json to package.json. +3. Run build from the repo root. (Minimum command is `./build.sh --quiet run-grunt`.) +4. Remove bower.json, gruntfile.js and package.json. +5. Check in _bower.json and new jquery.validate.unobtrusive.min.js file. \ No newline at end of file diff --git a/src/Mvc/test/WebSites/GenericHostWebSite/_gruntfile.js b/src/Mvc/test/WebSites/GenericHostWebSite/_gruntfile.js new file mode 100644 index 000000000000..22b35580a74c --- /dev/null +++ b/src/Mvc/test/WebSites/GenericHostWebSite/_gruntfile.js @@ -0,0 +1,20 @@ +module.exports = function (grunt) { + grunt.initConfig({ + bower: { + install: { + options: { + targetDir: "wwwroot/lib", + layout: "byComponent", + cleanTargetDir: false + } + } + } + }); + + // This command registers the default task which will install bower packages into wwwroot/lib + grunt.registerTask("default", ["bower:install"]); + + // The following line loads the grunt plugins. + // This line needs to be at the end of this file. + grunt.loadNpmTasks("grunt-bower-task"); +}; \ No newline at end of file diff --git a/src/Mvc/test/WebSites/GenericHostWebSite/_package.json b/src/Mvc/test/WebSites/GenericHostWebSite/_package.json new file mode 100644 index 000000000000..45df438fd2a0 --- /dev/null +++ b/src/Mvc/test/WebSites/GenericHostWebSite/_package.json @@ -0,0 +1,10 @@ +{ + "version": "0.0.0", + "name": "GenericHostWebSite", + "description": "Web site demonstrating various validations.", + "private": true, + "devDependencies": { + "grunt": "^0.4.5", + "grunt-bower-task": "^0.4.0" + } +} \ No newline at end of file diff --git a/src/Mvc/test/WebSites/GenericHostWebSite/readme.md b/src/Mvc/test/WebSites/GenericHostWebSite/readme.md new file mode 100644 index 000000000000..978f55e18d96 --- /dev/null +++ b/src/Mvc/test/WebSites/GenericHostWebSite/readme.md @@ -0,0 +1,4 @@ +GenericHostWebSite +=== + +This web site illustrates the use of the Generic Host APIs in Program.cs. diff --git a/src/Mvc/test/WebSites/GenericHostWebSite/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js b/src/Mvc/test/WebSites/GenericHostWebSite/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js new file mode 100644 index 000000000000..be9a38a4cfce --- /dev/null +++ b/src/Mvc/test/WebSites/GenericHostWebSite/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js @@ -0,0 +1,5 @@ +/* +** Unobtrusive validation support library for jQuery and jQuery Validate +** Copyright (C) Microsoft Corporation. All rights reserved. +*/ +!function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("
  • ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function m(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=p.unobtrusive.options||{},m=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),m("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),m("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),m("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var u,p=a.validator,v="unobtrusiveValidation";p.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=m(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){p.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=m(this);a&&a.attachValidation()})}},u=p.unobtrusive.adapters,u.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},u.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},u.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},u.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},p.addMethod("__dummy__",function(a,e,n){return!0}),p.addMethod("regex",function(a,e,n){var t;return this.optional(e)?!0:(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),p.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),p.methods.extension?(u.addSingleVal("accept","mimtype"),u.addSingleVal("extension","extension")):u.addSingleVal("extension","extension","accept"),u.addSingleVal("regex","pattern"),u.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),u.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),u.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),u.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),u.add("required",function(a){("INPUT"!==a.element.tagName.toUpperCase()||"CHECKBOX"!==a.element.type.toUpperCase())&&e(a,"required",!0)}),u.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),u.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),a(function(){p.unobtrusive.parse(document)})}(jQuery); \ No newline at end of file diff --git a/src/Shared/Hosting.WebHostBuilderFactory/Directory.Build.props b/src/Shared/Hosting.WebHostBuilderFactory/Directory.Build.props deleted file mode 100644 index 29e539295157..000000000000 --- a/src/Shared/Hosting.WebHostBuilderFactory/Directory.Build.props +++ /dev/null @@ -1,8 +0,0 @@ - - - - Internal.WebHostBuilderFactory.Sources - true - false - - diff --git a/src/Shared/Hosting.WebHostBuilderFactory/FactoryResolutionResult.cs b/src/Shared/Hosting.WebHostBuilderFactory/FactoryResolutionResult.cs deleted file mode 100644 index 745cca7ebd44..000000000000 --- a/src/Shared/Hosting.WebHostBuilderFactory/FactoryResolutionResult.cs +++ /dev/null @@ -1,54 +0,0 @@ -// 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 System; - -namespace Microsoft.AspNetCore.Hosting.WebHostBuilderFactory -{ - internal class FactoryResolutionResult - { - public FactoryResolutionResultKind ResultKind { get; set; } - public Type ProgramType { get; set; } - public Func WebHostFactory { get; set; } - public Func WebHostBuilderFactory { get; set; } - - internal static FactoryResolutionResult NoBuildWebHost(Type programType) => - new FactoryResolutionResult - { - ProgramType = programType, - ResultKind = FactoryResolutionResultKind.NoBuildWebHost - }; - - internal static FactoryResolutionResult NoCreateWebHostBuilder(Type programType) => - new FactoryResolutionResult - { - ProgramType = programType, - ResultKind = FactoryResolutionResultKind.NoCreateWebHostBuilder - }; - - internal static FactoryResolutionResult NoEntryPoint() => - new FactoryResolutionResult - { - ResultKind = FactoryResolutionResultKind.NoEntryPoint - }; - - internal static FactoryResolutionResult Succeded(Func factory, Type programType) => new FactoryResolutionResult - { - ProgramType = programType, - ResultKind = FactoryResolutionResultKind.Success, - WebHostFactory = factory - }; - - internal static FactoryResolutionResult Succeded(Func factory, Type programType) => new FactoryResolutionResult - { - ProgramType = programType, - ResultKind = FactoryResolutionResultKind.Success, - WebHostBuilderFactory = factory, - WebHostFactory = args => - { - var builder = factory(args); - return (TWebHost)builder.GetType().GetMethod("Build").Invoke(builder, Array.Empty()); - } - }; - } -} diff --git a/src/Shared/Hosting.WebHostBuilderFactory/FactoryResolutionResultKind.cs b/src/Shared/Hosting.WebHostBuilderFactory/FactoryResolutionResultKind.cs deleted file mode 100644 index bb970d21a491..000000000000 --- a/src/Shared/Hosting.WebHostBuilderFactory/FactoryResolutionResultKind.cs +++ /dev/null @@ -1,14 +0,0 @@ -// 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. - - -namespace Microsoft.AspNetCore.Hosting.WebHostBuilderFactory -{ - internal enum FactoryResolutionResultKind - { - Success, - NoEntryPoint, - NoCreateWebHostBuilder, - NoBuildWebHost - } -} diff --git a/src/Shared/Hosting.WebHostBuilderFactory/WebHostFactoryResolver.cs b/src/Shared/Hosting.WebHostBuilderFactory/WebHostFactoryResolver.cs deleted file mode 100644 index 916b15e020a4..000000000000 --- a/src/Shared/Hosting.WebHostBuilderFactory/WebHostFactoryResolver.cs +++ /dev/null @@ -1,68 +0,0 @@ -// 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 System; -using System.Reflection; - -namespace Microsoft.AspNetCore.Hosting.WebHostBuilderFactory -{ - internal class WebHostFactoryResolver - { - public static readonly string CreateWebHostBuilder = nameof(CreateWebHostBuilder); - public static readonly string BuildWebHost = nameof(BuildWebHost); - - public static FactoryResolutionResult ResolveWebHostBuilderFactory(Assembly assembly) - { - var programType = assembly?.EntryPoint?.DeclaringType; - if (programType == null) - { - return FactoryResolutionResult.NoEntryPoint(); - } - - var factory = programType.GetTypeInfo().GetDeclaredMethod(CreateWebHostBuilder); - if (factory == null || - !typeof(TWebhostBuilder).IsAssignableFrom(factory.ReturnType) || - factory.GetParameters().Length != 1 || - !typeof(string []).Equals(factory.GetParameters()[0].ParameterType)) - { - return FactoryResolutionResult.NoCreateWebHostBuilder(programType); - } - - return FactoryResolutionResult.Succeded(args => (TWebhostBuilder)factory.Invoke(null, new object[] { args }), programType); - } - - public static FactoryResolutionResult ResolveWebHostFactory(Assembly assembly) - { - // We want to give priority to BuildWebHost over CreateWebHostBuilder for backwards - // compatibility with existing projects that follow the old pattern. - var findResult = ResolveWebHostBuilderFactory(assembly); - switch (findResult.ResultKind) - { - case FactoryResolutionResultKind.NoEntryPoint: - return findResult; - case FactoryResolutionResultKind.Success: - case FactoryResolutionResultKind.NoCreateWebHostBuilder: - var buildWebHostMethod = findResult.ProgramType.GetTypeInfo().GetDeclaredMethod(BuildWebHost); - if (buildWebHostMethod == null || - !typeof(TWebhost).IsAssignableFrom(buildWebHostMethod.ReturnType) || - buildWebHostMethod.GetParameters().Length != 1 || - !typeof(string[]).Equals(buildWebHostMethod.GetParameters()[0].ParameterType)) - { - if (findResult.ResultKind == FactoryResolutionResultKind.Success) - { - return findResult; - } - - return FactoryResolutionResult.NoBuildWebHost(findResult.ProgramType); - } - else - { - return FactoryResolutionResult.Succeded(args => (TWebhost)buildWebHostMethod.Invoke(null, new object[] { args }), findResult.ProgramType); - } - case FactoryResolutionResultKind.NoBuildWebHost: - default: - throw new InvalidOperationException(); - } - } - } -} From c8a9ec26d86828d08208725869aab52d3b4068e4 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 11 Jan 2019 09:00:59 -0800 Subject: [PATCH 2/7] Update src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj Co-Authored-By: Tratcher --- src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj b/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj index b6744c1360b5..00423705cc5a 100644 --- a/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj +++ b/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj @@ -11,7 +11,7 @@ - + From 1e301b40f9d8f8475168f620b60521e35000f917 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 11 Jan 2019 09:01:06 -0800 Subject: [PATCH 3/7] Update src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Microsoft.AspNetCore.Mvc.Testing.csproj Co-Authored-By: Tratcher --- .../Microsoft.AspNetCore.Mvc.Testing.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Microsoft.AspNetCore.Mvc.Testing.csproj b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Microsoft.AspNetCore.Mvc.Testing.csproj index da9de4204560..1500aa2b18d7 100644 --- a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Microsoft.AspNetCore.Mvc.Testing.csproj +++ b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Microsoft.AspNetCore.Mvc.Testing.csproj @@ -12,7 +12,7 @@ - + From f24ca69bb6e2dafafe91a58c282177fce60fe77d Mon Sep 17 00:00:00 2001 From: Chris R Date: Fri, 11 Jan 2019 14:17:17 -0800 Subject: [PATCH 4/7] More virtual, resources, cleanup --- .../Microsoft.AspNetCore.Mvc.Testing.csproj | 1 + .../Properties/Resources.Designer.cs | 12 +++--- .../Resources.resx | 4 +- .../WebApplicationFactory.cs | 40 ++++++++++++++++--- .../WebSites/BasicWebSite/BasicWebSite.csproj | 10 +---- .../GenericHostWebSite.csproj | 8 ---- 6 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Microsoft.AspNetCore.Mvc.Testing.csproj b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Microsoft.AspNetCore.Mvc.Testing.csproj index 1500aa2b18d7..36f14c1bc817 100644 --- a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Microsoft.AspNetCore.Mvc.Testing.csproj +++ b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Microsoft.AspNetCore.Mvc.Testing.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Properties/Resources.Designer.cs b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Properties/Resources.Designer.cs index aa246881ebb7..e5c4f62c9b11 100644 --- a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Properties/Resources.Designer.cs +++ b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Properties/Resources.Designer.cs @@ -25,18 +25,18 @@ internal static string FormatInvalidAssemblyEntryPoint(object p0) => string.Format(CultureInfo.CurrentCulture, GetString("InvalidAssemblyEntryPoint"), p0); /// - /// No method 'public static {0} CreateWebHostBuilder(string[] args)' found on '{1}'. Alternatively, {2} can be extended and 'protected virtual {0} {3}()' can be overridden to provide your own {0} instance. + /// No method 'public static {0} CreateHostBuilder(string[] args)' or 'public static {1} CreateWebHostBuilder(string[] args)' found on '{2}'. Alternatively, {3} can be extended and '{4}' or '{5}' can be overridden to provide your own instance. /// - internal static string MissingCreateWebHostBuilderMethod + internal static string MissingBuilderMethod { - get => GetString("MissingCreateWebHostBuilderMethod"); + get => GetString("MissingBuilderMethod"); } /// - /// No method 'public static {0} CreateWebHostBuilder(string[] args)' found on '{1}'. Alternatively, {2} can be extended and 'protected virtual {0} {3}()' can be overridden to provide your own {0} instance. + /// No method 'public static {0} CreateHostBuilder(string[] args)' or 'public static {1} CreateWebHostBuilder(string[] args)' found on '{2}'. Alternatively, {3} can be extended and '{4}' or '{5}' can be overridden to provide your own instance. /// - internal static string FormatMissingCreateWebHostBuilderMethod(object p0, object p1, object p2, object p3) - => string.Format(CultureInfo.CurrentCulture, GetString("MissingCreateWebHostBuilderMethod"), p0, p1, p2, p3); + internal static string FormatMissingBuilderMethod(object p0, object p1, object p2, object p3, object p4, object p5) + => string.Format(CultureInfo.CurrentCulture, GetString("MissingBuilderMethod"), p0, p1, p2, p3, p4, p5); /// /// Can't find'{0}'. This file is required for functional tests to run properly. There should be a copy of the file on your source project bin folder. If that is not the case, make sure that the property PreserveCompilationContext is set to true on your project file. E.g '<PreserveCompilationContext>true</PreserveCompilationContext>'. For functional tests to work they need to either run from the build output folder or the {1} file from your application's output directory must be copied to the folder where the tests are running on. A common cause for this error is having shadow copying enabled when the tests run. diff --git a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Resources.resx b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Resources.resx index adf4045ebe0a..fad454a31955 100644 --- a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Resources.resx +++ b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/Resources.resx @@ -120,8 +120,8 @@ The provided Type '{0}' does not belong to an assembly with an entry point. A common cause for this error is providing a Type from a class library. - - No method 'public static {0} CreateWebHostBuilder(string[] args)' found on '{1}'. Alternatively, {2} can be extended and 'protected virtual {0} {3}()' can be overridden to provide your own {0} instance. + + No method 'public static {0} CreateHostBuilder(string[] args)' or 'public static {1} CreateWebHostBuilder(string[] args)' found on '{2}'. Alternatively, {3} can be extended and '{4}' or '{5}' can be overridden to provide your own instance. Can't find'{0}'. This file is required for functional tests to run properly. There should be a copy of the file on your source project bin folder. If that is not the case, make sure that the property PreserveCompilationContext is set to true on your project file. E.g '<PreserveCompilationContext>true</PreserveCompilationContext>'. For functional tests to work they need to either run from the build output folder or the {1} file from your application's output directory must be copied to the folder where the tests are running on. A common cause for this error is having shadow copying enabled when the tests run. diff --git a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs index bf2b7e411cb9..043461252ec2 100644 --- a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs +++ b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs @@ -13,6 +13,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyModel; using Microsoft.Extensions.Hosting; +using EnvironmentName = Microsoft.Extensions.Hosting.EnvironmentName; namespace Microsoft.AspNetCore.Mvc.Testing { @@ -70,7 +71,14 @@ public WebApplicationFactory() /// /// Gets the created by this . /// - public TestServer Server => _server; + public TestServer Server + { + get + { + EnsureServer(); + return _server; + } + } /// /// Gets the of factories created from this factory @@ -123,12 +131,11 @@ private void EnsureServer() EnsureDepsFile(); - var hostBuilder = HostFactoryResolver.ResolveHostBuilderFactory(typeof(TEntryPoint).Assembly)?.Invoke(Array.Empty()); + var hostBuilder = CreateHostBuilder(); if (hostBuilder != null) { hostBuilder.ConfigureWebHost(webHostBuilder => { - webHostBuilder.UseEnvironment("Development"); SetContentRoot(webHostBuilder); _configuration(webHostBuilder); webHostBuilder.UseTestServer(); @@ -285,11 +292,30 @@ private void EnsureDepsFile() } } + /// + /// Creates a used to set up . + /// + /// + /// The default implementation of this method looks for a public static IHostBuilder CreateHostBuilder(string[] args) + /// method defined on the entry point of the assembly of and invokes it passing an empty string + /// array as arguments. + /// + /// A instance. + protected virtual IHostBuilder CreateHostBuilder() + { + var hostBuilder = HostFactoryResolver.ResolveHostBuilderFactory(typeof(TEntryPoint).Assembly)?.Invoke(Array.Empty()); + if (hostBuilder != null) + { + hostBuilder.UseEnvironment(EnvironmentName.Development); + } + return hostBuilder; + } + /// /// Creates a used to set up . /// /// - /// The default implementation of this method looks for a public static IWebHostBuilder CreateDefaultBuilder(string[] args) + /// The default implementation of this method looks for a public static IWebHostBuilder CreateWebHostBuilder(string[] args) /// method defined on the entry point of the assembly of and invokes it passing an empty string /// array as arguments. /// @@ -299,15 +325,17 @@ protected virtual IWebHostBuilder CreateWebHostBuilder() var builder = WebHostBuilderFactory.CreateFromTypesAssemblyEntryPoint(Array.Empty()); if (builder == null) { - throw new InvalidOperationException(Resources.FormatMissingCreateWebHostBuilderMethod( + throw new InvalidOperationException(Resources.FormatMissingBuilderMethod( + nameof(IHostBuilder), nameof(IWebHostBuilder), typeof(TEntryPoint).Assembly.EntryPoint.DeclaringType.FullName, typeof(WebApplicationFactory).Name, + nameof(CreateHostBuilder), nameof(CreateWebHostBuilder))); } else { - return builder.UseEnvironment("Development"); + return builder.UseEnvironment(EnvironmentName.Development); } } diff --git a/src/Mvc/test/WebSites/BasicWebSite/BasicWebSite.csproj b/src/Mvc/test/WebSites/BasicWebSite/BasicWebSite.csproj index a46afe57e647..d452f269a8f7 100644 --- a/src/Mvc/test/WebSites/BasicWebSite/BasicWebSite.csproj +++ b/src/Mvc/test/WebSites/BasicWebSite/BasicWebSite.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.0 @@ -16,14 +16,6 @@ - - - - - diff --git a/src/Mvc/test/WebSites/GenericHostWebSite/GenericHostWebSite.csproj b/src/Mvc/test/WebSites/GenericHostWebSite/GenericHostWebSite.csproj index 68cc40b8ae9b..e4c1a38652d4 100644 --- a/src/Mvc/test/WebSites/GenericHostWebSite/GenericHostWebSite.csproj +++ b/src/Mvc/test/WebSites/GenericHostWebSite/GenericHostWebSite.csproj @@ -15,14 +15,6 @@ - - - - - From e916871cd1d72c296967819d21491112c83c1958 Mon Sep 17 00:00:00 2001 From: Chris R Date: Fri, 11 Jan 2019 16:05:41 -0800 Subject: [PATCH 5/7] Remove build artifact --- build/artifacts.props | 3 --- 1 file changed, 3 deletions(-) diff --git a/build/artifacts.props b/build/artifacts.props index ef185c5628ce..8b0c2d49705b 100644 --- a/build/artifacts.props +++ b/build/artifacts.props @@ -96,9 +96,6 @@ This can be done once #4246 is complete, and done in conjunction with converting - - - From 6ee1615ef4221b46868505f7d9a0e11077141e1d Mon Sep 17 00:00:00 2001 From: Chris R Date: Mon, 14 Jan 2019 11:21:41 -0800 Subject: [PATCH 6/7] Allow UseStartup to be called twice. --- .../Hosting/src/GenericHost/GenericWebHostBuilder.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Hosting/Hosting/src/GenericHost/GenericWebHostBuilder.cs b/src/Hosting/Hosting/src/GenericHost/GenericWebHostBuilder.cs index bf7c089f9599..b38bf97f05e3 100644 --- a/src/Hosting/Hosting/src/GenericHost/GenericWebHostBuilder.cs +++ b/src/Hosting/Hosting/src/GenericHost/GenericWebHostBuilder.cs @@ -203,9 +203,14 @@ public IWebHostBuilder UseDefaultServiceProvider(Action { - UseStartup(startupType, context, services); + if (_builder.Properties.TryGetValue("UseStartup.StartupType", out var cachedType) && (Type)cachedType == startupType) + { + UseStartup(startupType, context, services); + } }); return this; From 71646af4d4eb6cd06df6cfeba26b3ea9c529e8ba Mon Sep 17 00:00:00 2001 From: Chris R Date: Mon, 14 Jan 2019 15:32:40 -0800 Subject: [PATCH 7/7] Add more extensibility --- .../WebApplicationFactory.cs | 33 +++++++++++++++- .../Infrastructure/MvcTestFixture.cs | 18 +++++++++ .../TestingInfrastructureInheritanceTests.cs | 38 ++++++++++++++++++- 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs index 043461252ec2..1524622bd4dc 100644 --- a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs +++ b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs @@ -108,7 +108,9 @@ internal virtual WebApplicationFactory WithWebHostBuilderCore(Actio var factory = new DelegatedWebApplicationFactory( ClientOptions, CreateServer, + CreateHost, CreateWebHostBuilder, + CreateHostBuilder, GetTestAssemblies, ConfigureClient, builder => @@ -140,8 +142,7 @@ private void EnsureServer() _configuration(webHostBuilder); webHostBuilder.UseTestServer(); }); - _host = hostBuilder.Build(); - _host.Start(); + _host = CreateHost(hostBuilder); _server = (TestServer)_host.Services.GetRequiredService(); return; } @@ -341,12 +342,28 @@ protected virtual IWebHostBuilder CreateWebHostBuilder() /// /// Creates the with the bootstrapped application in . + /// This is only called for applications using . Applications based on + /// will use instead. /// /// The used to /// create the server. /// The with the bootstrapped application. protected virtual TestServer CreateServer(IWebHostBuilder builder) => new TestServer(builder); + /// + /// Creates the with the bootstrapped application in . + /// This is only called for applications using . Applications based on + /// will use instead. + /// + /// The used to create the host. + /// The with the bootstrapped application. + protected virtual IHost CreateHost(IHostBuilder builder) + { + var host = builder.Build(); + host.Start(); + return host; + } + /// /// Gives a fixture an opportunity to configure the application before it gets built. /// @@ -481,21 +498,27 @@ protected virtual void Dispose(bool disposing) private class DelegatedWebApplicationFactory : WebApplicationFactory { private readonly Func _createServer; + private readonly Func _createHost; private readonly Func _createWebHostBuilder; + private readonly Func _createHostBuilder; private readonly Func> _getTestAssemblies; private readonly Action _configureClient; public DelegatedWebApplicationFactory( WebApplicationFactoryClientOptions options, Func createServer, + Func createHost, Func createWebHostBuilder, + Func createHostBuilder, Func> getTestAssemblies, Action configureClient, Action configureWebHost) { ClientOptions = new WebApplicationFactoryClientOptions(options); _createServer = createServer; + _createHost = createHost; _createWebHostBuilder = createWebHostBuilder; + _createHostBuilder = createHostBuilder; _getTestAssemblies = getTestAssemblies; _configureClient = configureClient; _configuration = configureWebHost; @@ -503,8 +526,12 @@ public DelegatedWebApplicationFactory( protected override TestServer CreateServer(IWebHostBuilder builder) => _createServer(builder); + protected override IHost CreateHost(IHostBuilder builder) => _createHost(builder); + protected override IWebHostBuilder CreateWebHostBuilder() => _createWebHostBuilder(); + protected override IHostBuilder CreateHostBuilder() => _createHostBuilder(); + protected override IEnumerable GetTestAssemblies() => _getTestAssemblies(); protected override void ConfigureWebHost(IWebHostBuilder builder) => _configuration(builder); @@ -516,7 +543,9 @@ internal override WebApplicationFactory WithWebHostBuilderCore(Acti return new DelegatedWebApplicationFactory( ClientOptions, _createServer, + _createHost, _createWebHostBuilder, + _createHostBuilder, _getTestAssemblies, _configureClient, builder => diff --git a/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/Infrastructure/MvcTestFixture.cs b/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/Infrastructure/MvcTestFixture.cs index cf1ed53098b1..1c85f8412d7b 100644 --- a/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/Infrastructure/MvcTestFixture.cs +++ b/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/Infrastructure/MvcTestFixture.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Testing; @@ -44,5 +45,22 @@ protected override TestServer CreateServer(IWebHostBuilder builder) CultureInfo.CurrentUICulture = originalUICulture; } } + + protected override IHost CreateHost(IHostBuilder builder) + { + var originalCulture = CultureInfo.CurrentCulture; + var originalUICulture = CultureInfo.CurrentUICulture; + try + { + CultureInfo.CurrentCulture = new CultureInfo("en-GB"); + CultureInfo.CurrentUICulture = new CultureInfo("en-US"); + return base.CreateHost(builder); + } + finally + { + CultureInfo.CurrentCulture = originalCulture; + CultureInfo.CurrentUICulture = originalUICulture; + } + } } } diff --git a/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/TestingInfrastructureInheritanceTests.cs b/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/TestingInfrastructureInheritanceTests.cs index 02c2e622c31a..09a11fb4f8da 100644 --- a/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/TestingInfrastructureInheritanceTests.cs +++ b/src/Mvc/test/Microsoft.AspNetCore.Mvc.FunctionalTests/TestingInfrastructureInheritanceTests.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.Hosting; using Xunit; namespace Microsoft.AspNetCore.Mvc.FunctionalTests @@ -14,7 +15,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests public class TestingInfrastructureInheritanceTests { [Fact] - public void TestingInfrastructure_WithWebHostBuilderRespectsCustomizations() + public void TestingInfrastructure_WebHost_WithWebHostBuilderRespectsCustomizations() { // Act var factory = new CustomizedFactory(); @@ -28,13 +29,36 @@ public void TestingInfrastructure_WithWebHostBuilderRespectsCustomizations() Assert.True(factory.CreateServerCalled); Assert.True(factory.CreateWebHostBuilderCalled); Assert.True(factory.GetTestAssembliesCalled); + Assert.True(factory.CreateHostBuilderCalled); + Assert.False(factory.CreateHostCalled); + } + + [Fact] + public void TestingInfrastructure_GenericHost_WithWithHostBuilderRespectsCustomizations() + { + // Act + var factory = new CustomizedFactory(); + var customized = factory + .WithWebHostBuilder(builder => factory.ConfigureWebHostCalled.Add("Customization")) + .WithWebHostBuilder(builder => factory.ConfigureWebHostCalled.Add("FurtherCustomization")); + var client = customized.CreateClient(); + + // Assert + Assert.Equal(new[] { "ConfigureWebHost", "Customization", "FurtherCustomization" }, factory.ConfigureWebHostCalled.ToArray()); + Assert.True(factory.GetTestAssembliesCalled); + Assert.True(factory.CreateHostBuilderCalled); + Assert.True(factory.CreateHostCalled); + Assert.False(factory.CreateServerCalled); + Assert.False(factory.CreateWebHostBuilderCalled); } private class CustomizedFactory : WebApplicationFactory where TEntryPoint : class { public bool GetTestAssembliesCalled { get; private set; } public bool CreateWebHostBuilderCalled { get; private set; } + public bool CreateHostBuilderCalled { get; private set; } public bool CreateServerCalled { get; private set; } + public bool CreateHostCalled { get; private set; } public IList ConfigureWebHostCalled { get; private set; } = new List(); protected override void ConfigureWebHost(IWebHostBuilder builder) @@ -49,12 +73,24 @@ protected override TestServer CreateServer(IWebHostBuilder builder) return base.CreateServer(builder); } + protected override IHost CreateHost(IHostBuilder builder) + { + CreateHostCalled = true; + return base.CreateHost(builder); + } + protected override IWebHostBuilder CreateWebHostBuilder() { CreateWebHostBuilderCalled = true; return base.CreateWebHostBuilder(); } + protected override IHostBuilder CreateHostBuilder() + { + CreateHostBuilderCalled = true; + return base.CreateHostBuilder(); + } + protected override IEnumerable GetTestAssemblies() { GetTestAssembliesCalled = true;