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
-
-
-
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/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;
diff --git a/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj b/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj
index f309bf0eea2c..00423705cc5a 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..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
@@ -11,10 +11,9 @@
-
-
-
+
+
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 8356180bd93e..1524622bd4dc 100644
--- a/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs
+++ b/src/Mvc/src/Microsoft.AspNetCore.Mvc.Testing/WebApplicationFactory.cs
@@ -8,8 +8,12 @@
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;
+using EnvironmentName = Microsoft.Extensions.Hosting.EnvironmentName;
namespace Microsoft.AspNetCore.Mvc.Testing
{
@@ -22,6 +26,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 =
@@ -66,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
@@ -96,7 +108,9 @@ internal virtual WebApplicationFactory WithWebHostBuilderCore(Actio
var factory = new DelegatedWebApplicationFactory(
ClientOptions,
CreateServer,
+ CreateHost,
CreateWebHostBuilder,
+ CreateHostBuilder,
GetTestAssemblies,
ConfigureClient,
builder =>
@@ -119,6 +133,19 @@ private void EnsureServer()
EnsureDepsFile();
+ var hostBuilder = CreateHostBuilder();
+ if (hostBuilder != null)
+ {
+ hostBuilder.ConfigureWebHost(webHostBuilder =>
+ {
+ SetContentRoot(webHostBuilder);
+ _configuration(webHostBuilder);
+ webHostBuilder.UseTestServer();
+ });
+ _host = CreateHost(hostBuilder);
+ _server = (TestServer)_host.Services.GetRequiredService();
+ return;
+ }
var builder = CreateWebHostBuilder();
SetContentRoot(builder);
@@ -266,11 +293,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.
///
@@ -280,26 +326,44 @@ 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);
}
}
///
/// 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.
///
@@ -425,6 +489,7 @@ protected virtual void Dispose(bool disposing)
}
_server?.Dispose();
+ _host?.Dispose();
}
_disposed = true;
@@ -433,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;
@@ -455,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);
@@ -468,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/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/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;
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/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/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..e4c1a38652d4
--- /dev/null
+++ b/src/Mvc/test/WebSites/GenericHostWebSite/GenericHostWebSite.csproj
@@ -0,0 +1,27 @@
+
+
+
+ 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