From 9cb0461512317d8ebdcb179f9c81db034c230adc Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Thu, 28 Jun 2018 16:48:49 -0700 Subject: [PATCH 01/26] Bumping version from 2.2.0 to 3.0.0 --- version.props | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/version.props b/version.props index 84d0ba366d..4f8a21571f 100644 --- a/version.props +++ b/version.props @@ -1,10 +1,10 @@ - + - 2.2.0 - preview1 + 3.0.0 + alpha1 - 0.6.0 - preview1 + 0.7.0 + alpha1 $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final From 86bfb3ba2c3387d1a1b6a2fbfadd99d5d83e69bd Mon Sep 17 00:00:00 2001 From: "Nate McMaster (automated)" Date: Mon, 2 Jul 2018 12:40:20 -0700 Subject: [PATCH 02/26] [automated] Change default branch to master --- .appveyor.yml | 2 +- .travis.yml | 2 +- .vsts-pipelines/builds/ci-internal.yml | 4 ++-- .vsts-pipelines/builds/ci-public.yml | 6 +++--- korebuild.json | 4 ++-- run.ps1 | 6 +++--- run.sh | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 4eea96ab69..d45bd5a1f8 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,7 +2,7 @@ init: - git config --global core.autocrlf true branches: only: - - dev + - master - /^release\/.*$/ - /^(.*\/)?ci-.*$/ build_script: diff --git a/.travis.yml b/.travis.yml index 64bdbb4441..ab3980055c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ addons: - libunwind8 branches: only: - - dev + - master - /^release\/.*$/ - /^(.*\/)?ci-.*$/ before_install: diff --git a/.vsts-pipelines/builds/ci-internal.yml b/.vsts-pipelines/builds/ci-internal.yml index d7ceb76378..c2c5336fd0 100644 --- a/.vsts-pipelines/builds/ci-internal.yml +++ b/.vsts-pipelines/builds/ci-internal.yml @@ -1,5 +1,5 @@ trigger: -- dev +- master - release/* resources: @@ -7,7 +7,7 @@ resources: - repository: buildtools type: git name: aspnet-BuildTools - ref: refs/heads/dev + ref: refs/heads/master phases: - template: .vsts-pipelines/templates/project-ci.yml@buildtools diff --git a/.vsts-pipelines/builds/ci-public.yml b/.vsts-pipelines/builds/ci-public.yml index b7f25723f8..507c89b025 100644 --- a/.vsts-pipelines/builds/ci-public.yml +++ b/.vsts-pipelines/builds/ci-public.yml @@ -1,5 +1,5 @@ trigger: -- dev +- master - release/* # See https://github.com/aspnet/BuildTools @@ -9,7 +9,7 @@ resources: type: github endpoint: DotNet-Bot GitHub Connection name: aspnet/BuildTools - ref: refs/heads/dev - + ref: refs/heads/master + phases: - template: .vsts-pipelines/templates/project-ci.yml@buildtools diff --git a/korebuild.json b/korebuild.json index bd5d51a51b..8a276a7f35 100644 --- a/korebuild.json +++ b/korebuild.json @@ -1,4 +1,4 @@ { - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", - "channel": "dev" + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json", + "channel": "master" } diff --git a/run.ps1 b/run.ps1 index 3b27382468..34604c7175 100644 --- a/run.ps1 +++ b/run.ps1 @@ -52,8 +52,8 @@ in the file are overridden by command line parameters. Example config file: ```json { - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", - "channel": "dev", + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json", + "channel": "master", "toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools" } ``` @@ -192,7 +192,7 @@ if (!$DotNetHome) { else { Join-Path $PSScriptRoot '.dotnet'} } -if (!$Channel) { $Channel = 'dev' } +if (!$Channel) { $Channel = 'master' } if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' } # Execute diff --git a/run.sh b/run.sh index 02aac15874..61f7a53385 100755 --- a/run.sh +++ b/run.sh @@ -248,7 +248,7 @@ if [ -f "$config_file" ]; then [ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source" fi -[ -z "$channel" ] && channel='dev' +[ -z "$channel" ] && channel='master' [ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' get_korebuild From 97c9510a95e676324ed8fa03d8b6dcf3b1c19ccf Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Tue, 3 Jul 2018 16:12:24 +0000 Subject: [PATCH 03/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 58 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index b78e93abea..fcf3bd8427 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-17090 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 + 3.0.0-alpha1-10000 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 + 3.0.0-alpha1-10016 2.0.0 2.1.0 2.2.0-preview1-26618-02 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 3e694b2ed8..3f870e51fe 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17090 -commithash:b19e903e946579cd9482089bce7d917e8bacd765 +version:3.0.0-alpha1-10000 +commithash:b7b88d08d55abc8b71de9abf16e26fc713e332cd From 3e0b689ac2ea72a8dee81f8ae3a349610ac1fb0c Mon Sep 17 00:00:00 2001 From: nulltoken Date: Fri, 6 Jul 2018 22:00:25 +0200 Subject: [PATCH 04/26] Ensure ClientHandler properly honors Host header (#1483) Fix #1481 --- .../ClientHandler.cs | 20 ++++++++++------ .../TestServerTests.cs | 24 +++++++++++++++++++ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.AspNetCore.TestHost/ClientHandler.cs b/src/Microsoft.AspNetCore.TestHost/ClientHandler.cs index 2109809d1a..5471e23d19 100644 --- a/src/Microsoft.AspNetCore.TestHost/ClientHandler.cs +++ b/src/Microsoft.AspNetCore.TestHost/ClientHandler.cs @@ -72,10 +72,20 @@ namespace Microsoft.AspNetCore.TestHost req.Method = request.Method.ToString(); req.Scheme = request.RequestUri.Scheme; - req.Host = HostString.FromUriComponent(request.RequestUri); - if (request.RequestUri.IsDefaultPort) + + foreach (var header in request.Headers) { - req.Host = new HostString(req.Host.Host); + req.Headers.Append(header.Key, header.Value.ToArray()); + } + + if (req.Host == null || !req.Host.HasValue) + { + // If Host wasn't explicitly set as a header, let's infer it from the Uri + req.Host = HostString.FromUriComponent(request.RequestUri); + if (request.RequestUri.IsDefaultPort) + { + req.Host = new HostString(req.Host.Host); + } } req.Path = PathString.FromUriComponent(request.RequestUri); @@ -87,10 +97,6 @@ namespace Microsoft.AspNetCore.TestHost } req.QueryString = QueryString.FromUriComponent(request.RequestUri); - foreach (var header in request.Headers) - { - req.Headers.Append(header.Key, header.Value.ToArray()); - } if (requestContent != null) { foreach (var header in requestContent.Headers) diff --git a/test/Microsoft.AspNetCore.TestHost.Tests/TestServerTests.cs b/test/Microsoft.AspNetCore.TestHost.Tests/TestServerTests.cs index b1eee1fd94..a4175a75cb 100644 --- a/test/Microsoft.AspNetCore.TestHost.Tests/TestServerTests.cs +++ b/test/Microsoft.AspNetCore.TestHost.Tests/TestServerTests.cs @@ -16,6 +16,7 @@ using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DiagnosticAdapter; using Microsoft.Extensions.Logging; +using Microsoft.Net.Http.Headers; using Xunit; namespace Microsoft.AspNetCore.TestHost @@ -576,6 +577,29 @@ namespace Microsoft.AspNetCore.TestHost Assert.NotNull(listener.UnhandledException?.Exception); } + [Theory] + [InlineData("http://localhost:12345")] + [InlineData("http://localhost:12345/")] + [InlineData("http://localhost:12345/hellohellohello")] + [InlineData("/isthereanybodyinthere?")] + public async Task ManuallySetHostWinsOverInferredHostFromRequestUri(string uri) + { + RequestDelegate appDelegate = ctx => + ctx.Response.WriteAsync(ctx.Request.Headers[HeaderNames.Host]); + + var builder = new WebHostBuilder().Configure(app => app.Run(appDelegate)); + var server = new TestServer(builder); + var client = server.CreateClient(); + + var request = new HttpRequestMessage(HttpMethod.Get, uri); + request.Headers.Host = "otherhost:5678"; + + var response = await client.SendAsync(request); + var responseBody = await response.Content.ReadAsStringAsync(); + + Assert.Equal("otherhost:5678", responseBody); + } + public class TestDiagnosticListener { public class OnBeginRequestEventData From a5b083a39bae974e95ff1a9437468a103e72f6ea Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 8 Jul 2018 19:53:56 +0000 Subject: [PATCH 05/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 60 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index fcf3bd8427..dce69c4f57 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 3.0.0-alpha1-10000 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 - 3.0.0-alpha1-10016 + 3.0.0-alpha1-10005 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 + 3.0.0-alpha1-10044 2.0.0 2.1.0 2.2.0-preview1-26618-02 @@ -46,7 +46,7 @@ 1.7.0-preview1-26617-01 4.6.0-preview1-26617-01 2.3.1 - 2.4.0-beta.1.build3945 + 2.4.0-rc.1.build4038 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 3f870e51fe..2395ab5956 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-10000 -commithash:b7b88d08d55abc8b71de9abf16e26fc713e332cd +version:3.0.0-alpha1-10005 +commithash:05570853de976a526462ca140a55b1ac59d9a351 From 8836de411408257dd75f5db5f7d6724bfb0fab9e Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 15 Jul 2018 19:57:18 +0000 Subject: [PATCH 06/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 70 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index dce69c4f57..21e8ba2ac9 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,37 +3,37 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 3.0.0-alpha1-10005 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 3.0.0-alpha1-10044 - 2.0.0 - 2.1.0 + 3.0.0-alpha1-10009 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 3.0.0-alpha1-10081 + 2.0.9 + 2.1.2 2.2.0-preview1-26618-02 1.0.1 15.6.1 @@ -41,10 +41,10 @@ 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26617-01 - 4.6.0-preview1-26617-01 - 1.7.0-preview1-26617-01 - 4.6.0-preview1-26617-01 + 4.6.0-preview1-26708-04 + 4.6.0-preview1-26708-04 + 1.7.0-preview1-26708-04 + 4.6.0-preview1-26708-04 2.3.1 2.4.0-rc.1.build4038 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 2395ab5956..c6adb40215 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-10005 -commithash:05570853de976a526462ca140a55b1ac59d9a351 +version:3.0.0-alpha1-10009 +commithash:86be4707e47d2f1930a982f2b59eacfc4196da33 From 53fb442446d83814d3305ab4968734570bea76d3 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 22 Jul 2018 12:58:19 -0700 Subject: [PATCH 07/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 58 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 21e8ba2ac9..9527249f85 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 3.0.0-alpha1-10009 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 - 3.0.0-alpha1-10081 + 3.0.0-alpha1-10011 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 + 3.0.0-alpha1-10123 2.0.9 2.1.2 2.2.0-preview1-26618-02 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index c6adb40215..4cfdfb010e 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-10009 -commithash:86be4707e47d2f1930a982f2b59eacfc4196da33 +version:3.0.0-alpha1-10011 +commithash:717c2eb1f91dafd2580c1a9b8e5064d12dd8c054 From 85fbb7125753bcc947cbcd307288f641544b2b36 Mon Sep 17 00:00:00 2001 From: Eilon Lipton Date: Tue, 24 Jul 2018 10:50:50 -0700 Subject: [PATCH 08/26] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 64ff041d5c..eac4268e4c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ Contributing ====== -Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo. +Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/master/CONTRIBUTING.md) in the Home repo. From a934c42fe142f2448dbfd31f1780d050b3a2ca87 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 29 Jul 2018 19:56:08 +0000 Subject: [PATCH 09/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 69 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 9527249f85..ae4b8fd825 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 3.0.0-alpha1-10011 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 - 3.0.0-alpha1-10123 + 3.0.0-alpha1-10015 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 + 3.0.0-alpha1-10173 2.0.9 2.1.2 2.2.0-preview1-26618-02 @@ -41,12 +41,13 @@ 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26708-04 - 4.6.0-preview1-26708-04 - 1.7.0-preview1-26708-04 - 4.6.0-preview1-26708-04 + 4.6.0-preview1-26727-04 + 4.6.0-preview1-26727-04 + 1.7.0-preview1-26727-04 + 4.6.0-preview1-26727-04 2.3.1 - 2.4.0-rc.1.build4038 + 2.4.0 + diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 4cfdfb010e..8c70cbad9f 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-10011 -commithash:717c2eb1f91dafd2580c1a9b8e5064d12dd8c054 +version:3.0.0-alpha1-10015 +commithash:3f36e5c2f061712f76f2766c435d2555681d5c55 From 09c2fe8911a3b8e9c263a4b510a0245c28c656ff Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 5 Aug 2018 19:52:46 +0000 Subject: [PATCH 10/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 58 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index ae4b8fd825..635f537e33 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 3.0.0-alpha1-10015 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 + 3.0.0-alpha1-20180731.2 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 2.0.9 2.1.2 2.2.0-preview1-26618-02 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 8c70cbad9f..fe0f897b25 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-10015 -commithash:3f36e5c2f061712f76f2766c435d2555681d5c55 +version:3.0.0-alpha1-20180731.2 +commithash:1179f1083695ac9213c8a70a4d1d6c45a52caf41 From f59ab6a8ed06741a9e2d3b933c42dd9e17f3877b Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 12 Aug 2018 19:59:53 +0000 Subject: [PATCH 11/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 66 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 635f537e33..6d7f8cfa4c 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 3.0.0-alpha1-20180731.2 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 + 3.0.0-alpha1-20180810.1 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 2.0.9 2.1.2 2.2.0-preview1-26618-02 @@ -41,10 +41,10 @@ 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26727-04 - 4.6.0-preview1-26727-04 - 1.7.0-preview1-26727-04 - 4.6.0-preview1-26727-04 + 4.6.0-preview1-26807-04 + 4.6.0-preview1-26807-04 + 1.7.0-preview1-26807-04 + 4.6.0-preview1-26807-04 2.3.1 2.4.0 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index fe0f897b25..c53be3fca9 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180731.2 -commithash:1179f1083695ac9213c8a70a4d1d6c45a52caf41 +version:3.0.0-alpha1-20180810.1 +commithash:45c32b4f020e14a9295be31866051a18d293309d From e54dcc023ed0b548fe318de72d2b27f40c427f03 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 19 Aug 2018 19:14:24 +0000 Subject: [PATCH 12/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 66 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 6d7f8cfa4c..e8332a7ed1 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 3.0.0-alpha1-20180810.1 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 + 3.0.0-alpha1-20180817.3 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 2.0.9 2.1.2 2.2.0-preview1-26618-02 @@ -41,10 +41,10 @@ 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26807-04 - 4.6.0-preview1-26807-04 - 1.7.0-preview1-26807-04 - 4.6.0-preview1-26807-04 + 4.6.0-preview1-26816-01 + 4.6.0-preview1-26816-01 + 1.7.0-preview1-26816-01 + 4.6.0-preview1-26816-01 2.3.1 2.4.0 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index c53be3fca9..7abb5ed14d 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180810.1 -commithash:45c32b4f020e14a9295be31866051a18d293309d +version:3.0.0-alpha1-20180817.3 +commithash:134cdbee9bee29dd3ccb654c67663b27b9ffa6c8 From 637dea8487fe6b95b1e91ee2c597e90b3b1b1765 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 26 Aug 2018 19:13:48 +0000 Subject: [PATCH 13/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 66 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index e8332a7ed1..8cf292882d 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 3.0.0-alpha1-20180817.3 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 + 3.0.0-alpha1-20180821.3 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 2.0.9 2.1.2 2.2.0-preview1-26618-02 @@ -41,10 +41,10 @@ 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26816-01 - 4.6.0-preview1-26816-01 - 1.7.0-preview1-26816-01 - 4.6.0-preview1-26816-01 + 4.6.0-preview1-26817-04 + 4.6.0-preview1-26817-04 + 1.7.0-preview1-26817-04 + 4.6.0-preview1-26817-04 2.3.1 2.4.0 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 7abb5ed14d..74c82096f1 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180817.3 -commithash:134cdbee9bee29dd3ccb654c67663b27b9ffa6c8 +version:3.0.0-alpha1-20180821.3 +commithash:0939a90812deb1c604eb9a4768869687495fc1dd From c9a4ee8b719ffb01eb44705d68efd158eb80c221 Mon Sep 17 00:00:00 2001 From: Alfred Myers Date: Mon, 27 Aug 2018 14:33:05 -0300 Subject: [PATCH 14/26] Change List to Action (#1480) --- .../WebHostBuilder.cs | 30 ++++--------------- 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/src/Microsoft.AspNetCore.Hosting/WebHostBuilder.cs b/src/Microsoft.AspNetCore.Hosting/WebHostBuilder.cs index 423b898cec..9ebc1e5a8b 100644 --- a/src/Microsoft.AspNetCore.Hosting/WebHostBuilder.cs +++ b/src/Microsoft.AspNetCore.Hosting/WebHostBuilder.cs @@ -25,13 +25,13 @@ namespace Microsoft.AspNetCore.Hosting public class WebHostBuilder : IWebHostBuilder { private readonly HostingEnvironment _hostingEnvironment; - private readonly List> _configureServicesDelegates; + private Action _configureServices; private IConfiguration _config; private WebHostOptions _options; private WebHostBuilderContext _context; private bool _webHostBuilt; - private List> _configureAppConfigurationBuilderDelegates; + private Action _configureAppConfigurationBuilder; /// /// Initializes a new instance of the class. @@ -39,8 +39,6 @@ namespace Microsoft.AspNetCore.Hosting public WebHostBuilder() { _hostingEnvironment = new HostingEnvironment(); - _configureServicesDelegates = new List>(); - _configureAppConfigurationBuilderDelegates = new List>(); _config = new ConfigurationBuilder() .AddEnvironmentVariables(prefix: "ASPNETCORE_") @@ -111,12 +109,7 @@ namespace Microsoft.AspNetCore.Hosting /// The . public IWebHostBuilder ConfigureServices(Action configureServices) { - if (configureServices == null) - { - throw new ArgumentNullException(nameof(configureServices)); - } - - _configureServicesDelegates.Add(configureServices); + _configureServices += configureServices; return this; } @@ -131,12 +124,7 @@ namespace Microsoft.AspNetCore.Hosting /// public IWebHostBuilder ConfigureAppConfiguration(Action configureDelegate) { - if (configureDelegate == null) - { - throw new ArgumentNullException(nameof(configureDelegate)); - } - - _configureAppConfigurationBuilderDelegates.Add(configureDelegate); + _configureAppConfigurationBuilder += configureDelegate; return this; } @@ -272,10 +260,7 @@ namespace Microsoft.AspNetCore.Hosting .SetBasePath(_hostingEnvironment.ContentRootPath) .AddConfiguration(_config); - foreach (var configureAppConfiguration in _configureAppConfigurationBuilderDelegates) - { - configureAppConfiguration(_context, builder); - } + _configureAppConfigurationBuilder?.Invoke(_context, builder); var configuration = builder.Build(); services.AddSingleton(configuration); @@ -329,10 +314,7 @@ namespace Microsoft.AspNetCore.Hosting } } - foreach (var configureServices in _configureServicesDelegates) - { - configureServices(_context, services); - } + _configureServices?.Invoke(_context, services); return services; } From 8ef26577ff2e03f69c2f11710f8c669e8dd20b0b Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 2 Sep 2018 19:13:51 +0000 Subject: [PATCH 15/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 66 ++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 8cf292882d..ec0e0f6176 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,47 +4,47 @@ 3.0.0-alpha1-20180821.3 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 2.0.9 2.1.2 2.2.0-preview1-26618-02 1.0.1 15.6.1 - 4.7.49 + 4.9.0 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26817-04 - 4.6.0-preview1-26817-04 - 1.7.0-preview1-26817-04 - 4.6.0-preview1-26817-04 + 4.6.0-preview1-26829-04 + 4.6.0-preview1-26829-04 + 1.7.0-preview1-26829-04 + 4.6.0-preview1-26829-04 2.3.1 2.4.0 From c3d0767375d5f7d6340ca149527d0c4ecbe2d061 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Wed, 5 Sep 2018 23:45:58 +0000 Subject: [PATCH 16/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 68 ++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index ec0e0f6176..709daa723a 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,47 +4,47 @@ 3.0.0-alpha1-20180821.3 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 2.0.9 - 2.1.2 - 2.2.0-preview1-26618-02 + 2.1.3 + 2.2.0-preview2-26905-02 1.0.1 15.6.1 4.9.0 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26829-04 - 4.6.0-preview1-26829-04 - 1.7.0-preview1-26829-04 - 4.6.0-preview1-26829-04 + 4.6.0-preview1-26831-06 + 4.6.0-preview1-26831-06 + 1.7.0-preview1-26831-06 + 4.6.0-preview1-26831-06 2.3.1 2.4.0 From c37c50964d1451c22d085803ec54ec697c7fb81a Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 9 Sep 2018 19:14:37 +0000 Subject: [PATCH 17/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 66 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 709daa723a..f4af3b20e4 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 3.0.0-alpha1-20180821.3 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 + 3.0.0-alpha1-20180907.9 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 2.0.9 2.1.3 2.2.0-preview2-26905-02 @@ -41,10 +41,10 @@ 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26831-06 - 4.6.0-preview1-26831-06 - 1.7.0-preview1-26831-06 - 4.6.0-preview1-26831-06 + 4.6.0-preview1-26905-03 + 4.6.0-preview1-26905-03 + 1.7.0-preview1-26905-03 + 4.6.0-preview1-26905-03 2.3.1 2.4.0 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 74c82096f1..86de522933 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180821.3 -commithash:0939a90812deb1c604eb9a4768869687495fc1dd +version:3.0.0-alpha1-20180907.9 +commithash:f997365a8832ff0a3cbd9a98df45734ac2723fa0 From 81383bba8052d018771b8e17c2bc73fc872729fd Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 16 Sep 2018 19:13:35 +0000 Subject: [PATCH 18/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 66 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index f4af3b20e4..ec79d547d5 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 3.0.0-alpha1-20180907.9 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 + 3.0.0-alpha1-20180911.2 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 2.0.9 2.1.3 2.2.0-preview2-26905-02 @@ -41,10 +41,10 @@ 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26905-03 - 4.6.0-preview1-26905-03 - 1.7.0-preview1-26905-03 - 4.6.0-preview1-26905-03 + 4.6.0-preview1-26907-04 + 4.6.0-preview1-26907-04 + 1.7.0-preview1-26907-04 + 4.6.0-preview1-26907-04 2.3.1 2.4.0 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 86de522933..a3511df82d 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180907.9 -commithash:f997365a8832ff0a3cbd9a98df45734ac2723fa0 +version:3.0.0-alpha1-20180911.2 +commithash:2a2b7dbea1b247930c41da497f4ea0b2bb756818 From f682c6ab209bc7c71c18bdf42ae2d358f2fdf82b Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 23 Sep 2018 12:13:02 -0700 Subject: [PATCH 19/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 60 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index ec79d547d5..910c24ee33 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 3.0.0-alpha1-20180911.2 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 + 3.0.0-alpha1-20180919.1 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 2.0.9 2.1.3 2.2.0-preview2-26905-02 @@ -43,7 +43,7 @@ 3.2.0 4.6.0-preview1-26907-04 4.6.0-preview1-26907-04 - 1.7.0-preview1-26907-04 + 1.6.0 4.6.0-preview1-26907-04 2.3.1 2.4.0 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index a3511df82d..9a87e4ccb7 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180911.2 -commithash:2a2b7dbea1b247930c41da497f4ea0b2bb756818 +version:3.0.0-alpha1-20180919.1 +commithash:3066ae0a230870ea07e3f132605b5e5493f8bbd4 From 7826b5bc89b69bea9c427d763722dfca871e2780 Mon Sep 17 00:00:00 2001 From: Eilon Lipton Date: Thu, 27 Sep 2018 15:32:13 -0700 Subject: [PATCH 20/26] Update LICENSE.txt --- LICENSE.txt | 207 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 197 insertions(+), 10 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 7b2956ecee..b3b180cd51 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,14 +1,201 @@ -Copyright (c) .NET Foundation and Contributors + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -All rights reserved. + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at + 1. Definitions. - http://www.apache.org/licenses/LICENSE-2.0 + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the -specific language governing permissions and limitations under the License. + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) .NET Foundation and Contributors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 2850e9987bf052053b2322a543b93a3e7cf960a4 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 30 Sep 2018 12:13:43 -0700 Subject: [PATCH 21/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 58 ++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 910c24ee33..e3cdd0557b 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,34 +4,34 @@ 3.0.0-alpha1-20180919.1 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 2.0.9 2.1.3 2.2.0-preview2-26905-02 @@ -43,7 +43,7 @@ 3.2.0 4.6.0-preview1-26907-04 4.6.0-preview1-26907-04 - 1.6.0 + 1.7.0-preview1-26907-04 4.6.0-preview1-26907-04 2.3.1 2.4.0 From 88d33cd665736e9c73298d24901c9dc99607d414 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 7 Oct 2018 12:14:08 -0700 Subject: [PATCH 22/26] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 62 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 62fcc11bab..5384b97df3 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,44 +3,44 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 3.0.0-alpha1-20180919.1 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 + 3.0.0-alpha1-20181004.7 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 2.0.9 2.1.3 - 2.2.0-preview3-26927-02 + 2.2.0-preview2-26905-02 1.0.1 15.6.1 4.9.0 2.0.3 1.4.0 - 3.2.0 + 4.0.0 4.6.0-preview1-26907-04 4.6.0-preview1-26907-04 1.7.0-preview1-26907-04 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 9a87e4ccb7..14c4ea8ed3 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180919.1 -commithash:3066ae0a230870ea07e3f132605b5e5493f8bbd4 +version:3.0.0-alpha1-20181004.7 +commithash:27fabdaf2b1d4753c3d2749581694ca65d78f7f2 From d7b9fd480765bdc01f06441f308fb288e6001049 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Tue, 30 Oct 2018 11:26:46 -0700 Subject: [PATCH 23/26] Update TFM to include netcoreapp3.0 --- src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/Tfm.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/Tfm.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/Tfm.cs index 56715d3c08..4fb0bb57ef 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/Tfm.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/Tfm.cs @@ -11,6 +11,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting public const string NetCoreApp20 = "netcoreapp2.0"; public const string NetCoreApp21 = "netcoreapp2.1"; public const string NetCoreApp22 = "netcoreapp2.2"; + public const string NetCoreApp30 = "netcoreapp3.0"; public static bool Matches(string tfm1, string tfm2) { From cfe9b26a34af15c4943240d790ee5d1a168290c9 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 13 Nov 2018 21:22:30 -0800 Subject: [PATCH 24/26] Added support for generic host based IWebHostBuilder (#1580) - This adds an implementation of IWebHostBuilder as a facade over the IHostBuilder. This removes the 2 container issue by executing the Startup.ConfigureServies and Startup.ConfigureContainer inline as part of building the IHostBuilder. - The implementation is highly compatible implementation since it exposes the same IWebHostBuilder interface. Existing extensions mostly work. - There are some caveats with this approach. - Injecting services into Startup is not extremely constrained to the services availble on HostBuilderContext. This includes the IHostingEnvironment and the IConfiguration. - IStartup is broken when using this pattern because it isn't composable. - The IStartupConfigureServicesFilter and IStartupConfigureContainer The before and after filters added in 2.1 are also broken because there's a single container (it could maybe be fixed by downcasting and doing something specific on the GenericHostBuilder instance). - Calling into IWebHostBuilder.Build will throw a NotSupportedException since this implementation is just a facade over the IHostBuilder. --- samples/GenericWebHost/Program.cs | 19 +- samples/GenericWebHost/WebHostExtensions.cs | 43 -- samples/GenericWebHost/WebHostService.cs | 62 -- .../GenericWebHost/WebHostServiceOptions.cs | 11 - .../GenericWebHostApplicationLifetime.cs | 24 + .../GenericHost/GenericWebHostBuilder.cs | 376 ++++++++++++ .../GenericWebHostServiceOptions.cs | 17 + .../GenericHost/GenericWebHostedService.cs | 201 +++++++ .../HostingStartupWebHostBuilder.cs | 79 +++ .../GenericHost/ISupportsStartup.cs | 14 + .../ISupportsUseDefaultServiceProvider.cs | 13 + .../GenericHostWebHostBuilderExtensions.cs | 16 + .../Internal/ConfigureContainerBuilder.cs | 2 +- .../Internal/ConfigureServicesBuilder.cs | 2 +- .../Internal/StartupLoader.cs | 6 +- .../Internal/WebHost.cs | 2 +- .../WebHostBuilderExtensions.cs | 35 +- .../Fakes/GenericWebHost.cs | 35 ++ .../Fakes/GenericWebHostBuilderWrapper.cs | 77 +++ .../Fakes/StartupNoServicesNoInterface.cs | 21 + .../Microsoft.AspNetCore.Hosting.Tests.csproj | 1 + .../WebHostBuilderTests.cs | 534 +++++++++++------- 22 files changed, 1250 insertions(+), 340 deletions(-) delete mode 100644 samples/GenericWebHost/WebHostExtensions.cs delete mode 100644 samples/GenericWebHost/WebHostService.cs delete mode 100644 samples/GenericWebHost/WebHostServiceOptions.cs create mode 100644 src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostApplicationLifetime.cs create mode 100644 src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostBuilder.cs create mode 100644 src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostServiceOptions.cs create mode 100644 src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostedService.cs create mode 100644 src/Microsoft.AspNetCore.Hosting/GenericHost/HostingStartupWebHostBuilder.cs create mode 100644 src/Microsoft.AspNetCore.Hosting/GenericHost/ISupportsStartup.cs create mode 100644 src/Microsoft.AspNetCore.Hosting/GenericHost/ISupportsUseDefaultServiceProvider.cs create mode 100644 src/Microsoft.AspNetCore.Hosting/GenericHostWebHostBuilderExtensions.cs create mode 100644 test/Microsoft.AspNetCore.Hosting.Tests/Fakes/GenericWebHost.cs create mode 100644 test/Microsoft.AspNetCore.Hosting.Tests/Fakes/GenericWebHostBuilderWrapper.cs create mode 100644 test/Microsoft.AspNetCore.Hosting.Tests/Fakes/StartupNoServicesNoInterface.cs diff --git a/samples/GenericWebHost/Program.cs b/samples/GenericWebHost/Program.cs index 4879031f56..653541ef7a 100644 --- a/samples/GenericWebHost/Program.cs +++ b/samples/GenericWebHost/Program.cs @@ -1,10 +1,9 @@ -using System; -using System.Net; -using System.Threading.Tasks; +using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; +using Microsoft.AspNetCore.Hosting; namespace GenericWebHost { @@ -19,22 +18,20 @@ namespace GenericWebHost config.AddJsonFile("appsettings.json", optional: true); config.AddCommandLine(args); }) - .ConfigureServices((hostContext, services) => - { - }) .UseFakeServer() - .ConfigureWebHost((hostContext, app) => + .ConfigureWebHost(builder => { - app.Run(async (context) => + builder.Configure(app => { - await context.Response.WriteAsync("Hello World!"); + app.Run(async (context) => + { + await context.Response.WriteAsync("Hello World!"); + }); }); }) .UseConsoleLifetime() .Build(); - var s = host.Services; - await host.RunAsync(); } } diff --git a/samples/GenericWebHost/WebHostExtensions.cs b/samples/GenericWebHost/WebHostExtensions.cs deleted file mode 100644 index bf5567d81a..0000000000 --- a/samples/GenericWebHost/WebHostExtensions.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Hosting.Internal; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.ObjectPool; - -namespace GenericWebHost -{ - public static class WebHostExtensions - { - public static IHostBuilder ConfigureWebHost(this IHostBuilder builder, Action configureApp) - { - return builder.ConfigureServices((bulderContext, services) => - { - services.Configure(options => - { - options.ConfigureApp = configureApp; - }); - services.AddHostedService(); - - var listener = new DiagnosticListener("Microsoft.AspNetCore"); - services.AddSingleton(listener); - services.AddSingleton(listener); - - services.AddTransient(); - services.AddScoped(); - - // Conjure up a RequestServices - services.AddTransient(); - services.AddTransient, DefaultServiceProviderFactory>(); - - // Ensure object pooling is available everywhere. - services.AddSingleton(); - }); - } - } -} diff --git a/samples/GenericWebHost/WebHostService.cs b/samples/GenericWebHost/WebHostService.cs deleted file mode 100644 index 1ac316178f..0000000000 --- a/samples/GenericWebHost/WebHostService.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Diagnostics; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder.Internal; -using Microsoft.AspNetCore.Hosting.Internal; -using Microsoft.AspNetCore.Hosting.Server; -using Microsoft.AspNetCore.Hosting.Server.Features; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; - -namespace GenericWebHost -{ - internal class WebHostService : IHostedService - { - public WebHostService(IOptions options, IServiceProvider services, HostBuilderContext hostBuilderContext, IServer server, - ILogger logger, DiagnosticListener diagnosticListener, IHttpContextFactory httpContextFactory) - { - Options = options?.Value ?? throw new System.ArgumentNullException(nameof(options)); - - if (Options.ConfigureApp == null) - { - throw new ArgumentException(nameof(Options.ConfigureApp)); - } - - Services = services ?? throw new ArgumentNullException(nameof(services)); - HostBuilderContext = hostBuilderContext ?? throw new ArgumentNullException(nameof(hostBuilderContext)); - Server = server ?? throw new ArgumentNullException(nameof(server)); - Logger = logger ?? throw new ArgumentNullException(nameof(logger)); - DiagnosticListener = diagnosticListener ?? throw new ArgumentNullException(nameof(diagnosticListener)); - HttpContextFactory = httpContextFactory ?? throw new ArgumentNullException(nameof(httpContextFactory)); - } - - public WebHostServiceOptions Options { get; } - public IServiceProvider Services { get; } - public HostBuilderContext HostBuilderContext { get; } - public IServer Server { get; } - public ILogger Logger { get; } - public DiagnosticListener DiagnosticListener { get; } - public IHttpContextFactory HttpContextFactory { get; } - - public Task StartAsync(CancellationToken cancellationToken) - { - Server.Features.Get()?.Addresses.Add("http://localhost:5000"); - - var builder = new ApplicationBuilder(Services, Server.Features); - Options.ConfigureApp(HostBuilderContext, builder); - var app = builder.Build(); - - var httpApp = new HostingApplication(app, Logger, DiagnosticListener, HttpContextFactory); - return Server.StartAsync(httpApp, cancellationToken); - } - - public Task StopAsync(CancellationToken cancellationToken) - { - return Server.StopAsync(cancellationToken); - } - } -} \ No newline at end of file diff --git a/samples/GenericWebHost/WebHostServiceOptions.cs b/samples/GenericWebHost/WebHostServiceOptions.cs deleted file mode 100644 index 123dcf8790..0000000000 --- a/samples/GenericWebHost/WebHostServiceOptions.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.Hosting; - -namespace GenericWebHost -{ - public class WebHostServiceOptions - { - public Action ConfigureApp { get; internal set; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostApplicationLifetime.cs b/src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostApplicationLifetime.cs new file mode 100644 index 0000000000..d95704154e --- /dev/null +++ b/src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostApplicationLifetime.cs @@ -0,0 +1,24 @@ +// 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.Threading; + +namespace Microsoft.AspNetCore.Hosting.Internal +{ + internal class GenericWebHostApplicationLifetime : IApplicationLifetime + { + private readonly Microsoft.Extensions.Hosting.IApplicationLifetime _applicationLifetime; + public GenericWebHostApplicationLifetime(Microsoft.Extensions.Hosting.IApplicationLifetime applicationLifetime) + { + _applicationLifetime = applicationLifetime; + } + + public CancellationToken ApplicationStarted => _applicationLifetime.ApplicationStarted; + + public CancellationToken ApplicationStopping => _applicationLifetime.ApplicationStopping; + + public CancellationToken ApplicationStopped => _applicationLifetime.ApplicationStopped; + + public void StopApplication() => _applicationLifetime.StopApplication(); + } +} diff --git a/src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostBuilder.cs b/src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostBuilder.cs new file mode 100644 index 0000000000..6a425883ea --- /dev/null +++ b/src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostBuilder.cs @@ -0,0 +1,376 @@ +// 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.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Runtime.ExceptionServices; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.ObjectPool; + +namespace Microsoft.AspNetCore.Hosting.Internal +{ + internal class GenericWebHostBuilder : IWebHostBuilder, ISupportsStartup, ISupportsUseDefaultServiceProvider + { + private readonly IHostBuilder _builder; + private readonly IConfiguration _config; + private readonly object _startupKey = new object(); + + private AggregateException _hostingStartupErrors; + private HostingStartupWebHostBuilder _hostingStartupWebHostBuilder; + + public GenericWebHostBuilder(IHostBuilder builder) + { + _builder = builder; + + _config = new ConfigurationBuilder() + .AddEnvironmentVariables(prefix: "ASPNETCORE_") + .Build(); + + _builder.ConfigureHostConfiguration(config => + { + config.AddConfiguration(_config); + + // We do this super early but still late enough that we can process the configuration + // wired up by calls to UseSetting + ExecuteHostingStartups(); + }); + + // IHostingStartup needs to be executed before any direct methods on the builder + // so register these callbacks first + _builder.ConfigureAppConfiguration((context, configurationBuilder) => + { + if (_hostingStartupWebHostBuilder != null) + { + var webhostContext = GetWebHostBuilderContext(context); + _hostingStartupWebHostBuilder.ConfigureAppConfiguration(webhostContext, configurationBuilder); + } + }); + + _builder.ConfigureServices((context, services) => + { + if (_hostingStartupWebHostBuilder != null) + { + var webhostContext = GetWebHostBuilderContext(context); + _hostingStartupWebHostBuilder.ConfigureServices(webhostContext, services); + } + }); + + _builder.ConfigureServices((context, services) => + { + var webhostContext = GetWebHostBuilderContext(context); + var webHostOptions = (WebHostOptions)context.Properties[typeof(WebHostOptions)]; + + // Add the IHostingEnvironment and IApplicationLifetime from Microsoft.AspNetCore.Hosting + services.AddSingleton(webhostContext.HostingEnvironment); + services.AddSingleton(); + + services.Configure(options => + { + // Set the options + options.WebHostOptions = webHostOptions; + // Store and forward any startup errors + options.HostingStartupExceptions = _hostingStartupErrors; + }); + + services.AddHostedService(); + + // REVIEW: This is bad since we don't own this type. Anybody could add one of these and it would mess things up + // We need to flow this differently + var listener = new DiagnosticListener("Microsoft.AspNetCore"); + services.TryAddSingleton(listener); + services.TryAddSingleton(listener); + + services.TryAddSingleton(); + services.TryAddScoped(); + services.TryAddSingleton(); + + // Conjure up a RequestServices + services.TryAddTransient(); + + // Ensure object pooling is available everywhere. + services.TryAddSingleton(); + + // Support UseStartup(assemblyName) + if (!string.IsNullOrEmpty(webHostOptions.StartupAssembly)) + { + try + { + var startupType = StartupLoader.FindStartupType(webHostOptions.StartupAssembly, webhostContext.HostingEnvironment.EnvironmentName); + UseStartup(startupType, context, services); + } + catch (Exception ex) when (webHostOptions.CaptureStartupErrors) + { + var capture = ExceptionDispatchInfo.Capture(ex); + + services.Configure(options => + { + options.ConfigureApplication = app => + { + // Throw if there was any errors initializing startup + capture.Throw(); + }; + }); + } + } + }); + } + + private void ExecuteHostingStartups() + { + var webHostOptions = new WebHostOptions(_config, Assembly.GetEntryAssembly()?.GetName().Name); + + if (webHostOptions.PreventHostingStartup) + { + return; + } + + var exceptions = new List(); + _hostingStartupWebHostBuilder = new HostingStartupWebHostBuilder(this); + + // Execute the hosting startup assemblies + foreach (var assemblyName in webHostOptions.GetFinalHostingStartupAssemblies().Distinct(StringComparer.OrdinalIgnoreCase)) + { + try + { + var assembly = Assembly.Load(new AssemblyName(assemblyName)); + + foreach (var attribute in assembly.GetCustomAttributes()) + { + var hostingStartup = (IHostingStartup)Activator.CreateInstance(attribute.HostingStartupType); + hostingStartup.Configure(_hostingStartupWebHostBuilder); + } + } + catch (Exception ex) + { + // Capture any errors that happen during startup + exceptions.Add(new InvalidOperationException($"Startup assembly {assemblyName} failed to execute. See the inner exception for more details.", ex)); + } + } + + if (exceptions.Count > 0) + { + _hostingStartupErrors = new AggregateException(exceptions); + } + } + + public IWebHost Build() + { + throw new NotSupportedException($"Building this implementation of {nameof(IWebHostBuilder)} is not supported."); + } + + public IWebHostBuilder ConfigureAppConfiguration(Action configureDelegate) + { + _builder.ConfigureAppConfiguration((context, builder) => + { + var webhostBuilderContext = GetWebHostBuilderContext(context); + configureDelegate(webhostBuilderContext, builder); + }); + + return this; + } + + public IWebHostBuilder ConfigureServices(Action configureServices) + { + return ConfigureServices((context, services) => configureServices(services)); + } + + public IWebHostBuilder ConfigureServices(Action configureServices) + { + _builder.ConfigureServices((context, builder) => + { + var webhostBuilderContext = GetWebHostBuilderContext(context); + configureServices(webhostBuilderContext, builder); + }); + + return this; + } + + public IWebHostBuilder UseDefaultServiceProvider(Action configure) + { + // REVIEW: This is a hack to change the builder with the HostBuilderContext in scope, + // we're not actually using configuration here + _builder.ConfigureAppConfiguration((context, _) => + { + var webHostBuilderContext = GetWebHostBuilderContext(context); + var options = new ServiceProviderOptions(); + configure(webHostBuilderContext, options); + + // This is only fine because this runs last + _builder.UseServiceProviderFactory(new DefaultServiceProviderFactory(options)); + }); + + return this; + } + + public IWebHostBuilder UseStartup(Type startupType) + { + _builder.ConfigureServices((context, services) => + { + UseStartup(startupType, context, services); + }); + + return this; + } + + private void UseStartup(Type startupType, HostBuilderContext context, IServiceCollection services) + { + var webHostBuilderContext = GetWebHostBuilderContext(context); + var webHostOptions = (WebHostOptions)context.Properties[typeof(WebHostOptions)]; + + ExceptionDispatchInfo startupError = null; + object instance = null; + ConfigureBuilder configureBuilder = null; + + try + { + // We cannot support methods that return IServiceProvider as that is terminal and we need ConfigureServices to compose + if (typeof(IStartup).IsAssignableFrom(startupType)) + { + throw new NotSupportedException($"{typeof(IStartup)} isn't supported"); + } + + instance = ActivatorUtilities.CreateInstance(new HostServiceProvider(webHostBuilderContext), startupType); + context.Properties[_startupKey] = instance; + + // Startup.ConfigureServices + var configureServicesBuilder = StartupLoader.FindConfigureServicesDelegate(startupType, context.HostingEnvironment.EnvironmentName); + var configureServices = configureServicesBuilder.Build(instance); + + configureServices(services); + + // REVIEW: We're doing this in the callback so that we have access to the hosting environment + // Startup.ConfigureContainer + var configureContainerBuilder = StartupLoader.FindConfigureContainerDelegate(startupType, context.HostingEnvironment.EnvironmentName); + if (configureContainerBuilder.MethodInfo != null) + { + var containerType = configureContainerBuilder.GetContainerType(); + // Store the builder in the property bag + _builder.Properties[typeof(ConfigureContainerBuilder)] = configureContainerBuilder; + + var actionType = typeof(Action<,>).MakeGenericType(typeof(HostBuilderContext), containerType); + + // Get the private ConfigureContainer method on this type then close over the container type + var configureCallback = GetType().GetMethod(nameof(ConfigureContainer), BindingFlags.NonPublic | BindingFlags.Instance) + .MakeGenericMethod(containerType) + .CreateDelegate(actionType, this); + + // _builder.ConfigureContainer(ConfigureContainer); + typeof(IHostBuilder).GetMethods().First(m => m.Name == nameof(IHostBuilder.ConfigureContainer)) + .MakeGenericMethod(containerType) + .Invoke(_builder, new object[] { configureCallback }); + } + + // Resolve Configure after calling ConfigureServices and ConfigureContainer + configureBuilder = StartupLoader.FindConfigureDelegate(startupType, context.HostingEnvironment.EnvironmentName); + } + catch (Exception ex) when (webHostOptions.CaptureStartupErrors) + { + startupError = ExceptionDispatchInfo.Capture(ex); + } + + // Startup.Configure + services.Configure(options => + { + options.ConfigureApplication = app => + { + // Throw if there was any errors initializing startup + startupError?.Throw(); + + // Execute Startup.Configure + if (instance != null && configureBuilder != null) + { + configureBuilder.Build(instance)(app); + } + }; + }); + } + + private void ConfigureContainer(HostBuilderContext context, TContainer container) + { + var instance = context.Properties[_startupKey]; + var builder = (ConfigureContainerBuilder)context.Properties[typeof(ConfigureContainerBuilder)]; + builder.Build(instance)(container); + } + + public IWebHostBuilder Configure(Action configure) + { + _builder.ConfigureServices((context, services) => + { + services.Configure(options => + { + options.ConfigureApplication = configure; + }); + }); + + return this; + } + + private WebHostBuilderContext GetWebHostBuilderContext(HostBuilderContext context) + { + if (!context.Properties.TryGetValue(typeof(WebHostBuilderContext), out var contextVal)) + { + var options = new WebHostOptions(context.Configuration, Assembly.GetEntryAssembly()?.GetName().Name); + var hostingEnvironment = new HostingEnvironment(); + hostingEnvironment.Initialize(context.HostingEnvironment.ContentRootPath, options); + + var webHostBuilderContext = new WebHostBuilderContext + { + Configuration = context.Configuration, + HostingEnvironment = hostingEnvironment + }; + context.Properties[typeof(WebHostBuilderContext)] = webHostBuilderContext; + context.Properties[typeof(WebHostOptions)] = options; + return webHostBuilderContext; + } + + return (WebHostBuilderContext)contextVal; + } + + public string GetSetting(string key) + { + return _config[key]; + } + + public IWebHostBuilder UseSetting(string key, string value) + { + _config[key] = value; + return this; + } + + // This exists just so that we can use ActivatorUtilities.CreateInstance on the Startup class + private class HostServiceProvider : IServiceProvider + { + private readonly WebHostBuilderContext _context; + + public HostServiceProvider(WebHostBuilderContext context) + { + _context = context; + } + + public object GetService(Type serviceType) + { + // The implementation of the HostingEnvironment supports both interfaces + if (serviceType == typeof(Microsoft.AspNetCore.Hosting.IHostingEnvironment) || serviceType == typeof(IHostingEnvironment)) + { + return _context.HostingEnvironment; + } + + if (serviceType == typeof(IConfiguration)) + { + return _context.Configuration; + } + + return null; + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostServiceOptions.cs b/src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostServiceOptions.cs new file mode 100644 index 0000000000..715c43514e --- /dev/null +++ b/src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostServiceOptions.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNetCore.Builder; + +namespace Microsoft.AspNetCore.Hosting.Internal +{ + internal class GenericWebHostServiceOptions + { + public Action ConfigureApplication { get; set; } + + public WebHostOptions WebHostOptions { get; set; } + + public AggregateException HostingStartupExceptions { get; set; } + } +} diff --git a/src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostedService.cs b/src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostedService.cs new file mode 100644 index 0000000000..8ec39059f0 --- /dev/null +++ b/src/Microsoft.AspNetCore.Hosting/GenericHost/GenericWebHostedService.cs @@ -0,0 +1,201 @@ +// 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.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting.Builder; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Hosting.Server.Features; +using Microsoft.AspNetCore.Hosting.Views; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Microsoft.Extensions.StackTrace.Sources; + +namespace Microsoft.AspNetCore.Hosting.Internal +{ + internal class GenericWebHostService : IHostedService + { + public GenericWebHostService(IOptions options, + IServer server, + ILogger logger, + DiagnosticListener diagnosticListener, + IHttpContextFactory httpContextFactory, + IApplicationBuilderFactory applicationBuilderFactory, + IEnumerable startupFilters, + IConfiguration configuration, + IHostingEnvironment hostingEnvironment) + { + Options = options.Value; + Server = server; + Logger = logger; + DiagnosticListener = diagnosticListener; + HttpContextFactory = httpContextFactory; + ApplicationBuilderFactory = applicationBuilderFactory; + StartupFilters = startupFilters; + Configuration = configuration; + HostingEnvironment = hostingEnvironment; + } + + public GenericWebHostServiceOptions Options { get; } + public IServer Server { get; } + public ILogger Logger { get; } + public DiagnosticListener DiagnosticListener { get; } + public IHttpContextFactory HttpContextFactory { get; } + public IApplicationBuilderFactory ApplicationBuilderFactory { get; } + public IEnumerable StartupFilters { get; } + public IConfiguration Configuration { get; } + public IHostingEnvironment HostingEnvironment { get; } + + public async Task StartAsync(CancellationToken cancellationToken) + { + HostingEventSource.Log.HostStart(); + + var serverAddressesFeature = Server.Features?.Get(); + var addresses = serverAddressesFeature?.Addresses; + if (addresses != null && !addresses.IsReadOnly && addresses.Count == 0) + { + var urls = Configuration[WebHostDefaults.ServerUrlsKey]; + if (!string.IsNullOrEmpty(urls)) + { + serverAddressesFeature.PreferHostingUrls = WebHostUtilities.ParseBool(Configuration, WebHostDefaults.PreferHostingUrlsKey); + + foreach (var value in urls.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) + { + addresses.Add(value); + } + } + } + + RequestDelegate application = null; + + try + { + Action configure = Options.ConfigureApplication; + + if (configure == null) + { + throw new InvalidOperationException($"No application configured. Please specify an application via IWebHostBuilder.UseStartup, IWebHostBuilder.Configure, or specifying the startup assembly via {nameof(WebHostDefaults.StartupAssemblyKey)} in the web host configuration."); + } + + var builder = ApplicationBuilderFactory.CreateBuilder(Server.Features); + + foreach (var filter in StartupFilters.Reverse()) + { + configure = filter.Configure(configure); + } + + configure(builder); + + // Build the request pipeline + application = builder.Build(); + } + catch (Exception ex) + { + Logger.ApplicationError(ex); + + if (!Options.WebHostOptions.CaptureStartupErrors) + { + throw; + } + + application = BuildErrorPageApplication(ex); + } + + var httpApplication = new HostingApplication(application, Logger, DiagnosticListener, HttpContextFactory); + + await Server.StartAsync(httpApplication, cancellationToken); + + if (addresses != null) + { + foreach (var address in addresses) + { + Logger.LogInformation("Now listening on: {address}", address); + } + } + + if (Logger.IsEnabled(LogLevel.Debug)) + { + foreach (var assembly in Options.WebHostOptions.GetFinalHostingStartupAssemblies()) + { + Logger.LogDebug("Loaded hosting startup assembly {assemblyName}", assembly); + } + } + + if (Options.HostingStartupExceptions != null) + { + foreach (var exception in Options.HostingStartupExceptions.InnerExceptions) + { + Logger.HostingStartupAssemblyError(exception); + } + } + } + + private RequestDelegate BuildErrorPageApplication(Exception exception) + { + if (exception is TargetInvocationException tae) + { + exception = tae.InnerException; + } + + var showDetailedErrors = HostingEnvironment.IsDevelopment() || Options.WebHostOptions.DetailedErrors; + + var model = new ErrorPageModel + { + RuntimeDisplayName = RuntimeInformation.FrameworkDescription + }; + var systemRuntimeAssembly = typeof(System.ComponentModel.DefaultValueAttribute).GetTypeInfo().Assembly; + var assemblyVersion = new AssemblyName(systemRuntimeAssembly.FullName).Version.ToString(); + var clrVersion = assemblyVersion; + model.RuntimeArchitecture = RuntimeInformation.ProcessArchitecture.ToString(); + var currentAssembly = typeof(ErrorPage).GetTypeInfo().Assembly; + model.CurrentAssemblyVesion = currentAssembly + .GetCustomAttribute() + .InformationalVersion; + model.ClrVersion = clrVersion; + model.OperatingSystemDescription = RuntimeInformation.OSDescription; + + if (showDetailedErrors) + { + var exceptionDetailProvider = new ExceptionDetailsProvider( + HostingEnvironment.ContentRootFileProvider, + sourceCodeLineCount: 6); + + model.ErrorDetails = exceptionDetailProvider.GetDetails(exception); + } + else + { + model.ErrorDetails = new ExceptionDetails[0]; + } + + var errorPage = new ErrorPage(model); + return context => + { + context.Response.StatusCode = 500; + context.Response.Headers["Cache-Control"] = "no-cache"; + return errorPage.ExecuteAsync(context); + }; + } + + public async Task StopAsync(CancellationToken cancellationToken) + { + try + { + await Server.StopAsync(cancellationToken); + } + finally + { + HostingEventSource.Log.HostStop(); + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Hosting/GenericHost/HostingStartupWebHostBuilder.cs b/src/Microsoft.AspNetCore.Hosting/GenericHost/HostingStartupWebHostBuilder.cs new file mode 100644 index 0000000000..52eaec8179 --- /dev/null +++ b/src/Microsoft.AspNetCore.Hosting/GenericHost/HostingStartupWebHostBuilder.cs @@ -0,0 +1,79 @@ +// 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 Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace Microsoft.AspNetCore.Hosting.Internal +{ + // We use this type to capture calls to the IWebHostBuilder so the we can properly order calls to + // to GenericHostWebHostBuilder. + internal class HostingStartupWebHostBuilder : IWebHostBuilder, ISupportsStartup, ISupportsUseDefaultServiceProvider + { + private readonly GenericWebHostBuilder _builder; + private Action _configureConfiguration; + private Action _configureServices; + + public HostingStartupWebHostBuilder(GenericWebHostBuilder builder) + { + _builder = builder; + } + + public IWebHost Build() + { + throw new NotSupportedException($"Building this implementation of {nameof(IWebHostBuilder)} is not supported."); + } + + public IWebHostBuilder ConfigureAppConfiguration(Action configureDelegate) + { + _configureConfiguration += configureDelegate; + return this; + } + + public IWebHostBuilder ConfigureServices(Action configureServices) + { + return ConfigureServices((context, services) => configureServices(services)); + } + + public IWebHostBuilder ConfigureServices(Action configureServices) + { + _configureServices += configureServices; + return this; + } + + public string GetSetting(string key) => _builder.GetSetting(key); + + public IWebHostBuilder UseSetting(string key, string value) + { + _builder.UseSetting(key, value); + return this; + } + + public void ConfigureServices(WebHostBuilderContext context, IServiceCollection services) + { + _configureServices?.Invoke(context, services); + } + + public void ConfigureAppConfiguration(WebHostBuilderContext context, IConfigurationBuilder builder) + { + _configureConfiguration?.Invoke(context, builder); + } + + public IWebHostBuilder UseDefaultServiceProvider(Action configure) + { + return _builder.UseDefaultServiceProvider(configure); + } + + public IWebHostBuilder Configure(Action configure) + { + return _builder.Configure(configure); + } + + public IWebHostBuilder UseStartup(Type startupType) + { + return _builder.UseStartup(startupType); + } + } +} diff --git a/src/Microsoft.AspNetCore.Hosting/GenericHost/ISupportsStartup.cs b/src/Microsoft.AspNetCore.Hosting/GenericHost/ISupportsStartup.cs new file mode 100644 index 0000000000..16322c8bea --- /dev/null +++ b/src/Microsoft.AspNetCore.Hosting/GenericHost/ISupportsStartup.cs @@ -0,0 +1,14 @@ +// 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 Microsoft.AspNetCore.Builder; + +namespace Microsoft.AspNetCore.Hosting.Internal +{ + internal interface ISupportsStartup + { + IWebHostBuilder Configure(Action configure); + IWebHostBuilder UseStartup(Type startupType); + } +} diff --git a/src/Microsoft.AspNetCore.Hosting/GenericHost/ISupportsUseDefaultServiceProvider.cs b/src/Microsoft.AspNetCore.Hosting/GenericHost/ISupportsUseDefaultServiceProvider.cs new file mode 100644 index 0000000000..bf9813cd6e --- /dev/null +++ b/src/Microsoft.AspNetCore.Hosting/GenericHost/ISupportsUseDefaultServiceProvider.cs @@ -0,0 +1,13 @@ +// 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 Microsoft.Extensions.DependencyInjection; + +namespace Microsoft.AspNetCore.Hosting.Internal +{ + internal interface ISupportsUseDefaultServiceProvider + { + IWebHostBuilder UseDefaultServiceProvider(Action configure); + } +} diff --git a/src/Microsoft.AspNetCore.Hosting/GenericHostWebHostBuilderExtensions.cs b/src/Microsoft.AspNetCore.Hosting/GenericHostWebHostBuilderExtensions.cs new file mode 100644 index 0000000000..ea903ad7b5 --- /dev/null +++ b/src/Microsoft.AspNetCore.Hosting/GenericHostWebHostBuilderExtensions.cs @@ -0,0 +1,16 @@ +using System; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Internal; + +namespace Microsoft.Extensions.Hosting +{ + public static class GenericHostWebHostBuilderExtensions + { + public static IHostBuilder ConfigureWebHost(this IHostBuilder builder, Action configure) + { + var webhostBuilder = new GenericWebHostBuilder(builder); + configure(webhostBuilder); + return builder; + } + } +} diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/ConfigureContainerBuilder.cs b/src/Microsoft.AspNetCore.Hosting/Internal/ConfigureContainerBuilder.cs index ed8d0fd06e..8791a918ab 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/ConfigureContainerBuilder.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/ConfigureContainerBuilder.cs @@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal public MethodInfo MethodInfo { get; } - public Func, Action> ConfigureContainerFilters { get; set; } + public Func, Action> ConfigureContainerFilters { get; set; } = f => f; public Action Build(object instance) => container => Invoke(instance, container); diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/ConfigureServicesBuilder.cs b/src/Microsoft.AspNetCore.Hosting/Internal/ConfigureServicesBuilder.cs index 4206d0d62a..cf9a69327d 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/ConfigureServicesBuilder.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/ConfigureServicesBuilder.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal public MethodInfo MethodInfo { get; } - public Func, Func> StartupServiceFilters { get; set; } + public Func, Func> StartupServiceFilters { get; set; } = f => f; public Func Build(object instance) => services => Invoke(instance, services); diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/StartupLoader.cs b/src/Microsoft.AspNetCore.Hosting/Internal/StartupLoader.cs index d7211d39d9..72dab81736 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/StartupLoader.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/StartupLoader.cs @@ -267,19 +267,19 @@ namespace Microsoft.AspNetCore.Hosting.Internal return type; } - private static ConfigureBuilder FindConfigureDelegate(Type startupType, string environmentName) + internal static ConfigureBuilder FindConfigureDelegate(Type startupType, string environmentName) { var configureMethod = FindMethod(startupType, "Configure{0}", environmentName, typeof(void), required: true); return new ConfigureBuilder(configureMethod); } - private static ConfigureContainerBuilder FindConfigureContainerDelegate(Type startupType, string environmentName) + internal static ConfigureContainerBuilder FindConfigureContainerDelegate(Type startupType, string environmentName) { var configureMethod = FindMethod(startupType, "Configure{0}Container", environmentName, typeof(void), required: false); return new ConfigureContainerBuilder(configureMethod); } - private static ConfigureServicesBuilder FindConfigureServicesDelegate(Type startupType, string environmentName) + internal static ConfigureServicesBuilder FindConfigureServicesDelegate(Type startupType, string environmentName) { var servicesMethod = FindMethod(startupType, "Configure{0}Services", environmentName, typeof(IServiceProvider), required: false) ?? FindMethod(startupType, "Configure{0}Services", environmentName, typeof(void), required: false); diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs b/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs index 3764427f63..0ff44958f1 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs @@ -192,7 +192,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal if (_startup == null) { - throw new InvalidOperationException($"No startup configured. Please specify startup via WebHostBuilder.UseStartup, WebHostBuilder.Configure, injecting {nameof(IStartup)} or specifying the startup assembly via {nameof(WebHostDefaults.StartupAssemblyKey)} in the web host configuration."); + throw new InvalidOperationException($"No application configured. Please specify startup via IWebHostBuilder.UseStartup, IWebHostBuilder.Configure, injecting {nameof(IStartup)} or specifying the startup assembly via {nameof(WebHostDefaults.StartupAssemblyKey)} in the web host configuration."); } } diff --git a/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs b/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs index 09c7e6d96b..63dd3257b8 100644 --- a/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs @@ -29,15 +29,21 @@ namespace Microsoft.AspNetCore.Hosting var startupAssemblyName = configureApp.GetMethodInfo().DeclaringType.GetTypeInfo().Assembly.GetName().Name; - return hostBuilder - .UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName) - .ConfigureServices(services => + hostBuilder.UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName); + + // Light up the ISupportsStartup implementation + if (hostBuilder is ISupportsStartup supportsStartup) + { + return supportsStartup.Configure(configureApp); + } + + return hostBuilder.ConfigureServices(services => + { + services.AddSingleton(sp => { - services.AddSingleton(sp => - { - return new DelegateStartup(sp.GetRequiredService>(), configureApp); - }); + return new DelegateStartup(sp.GetRequiredService>(), configureApp); }); + }); } @@ -51,8 +57,15 @@ namespace Microsoft.AspNetCore.Hosting { var startupAssemblyName = startupType.GetTypeInfo().Assembly.GetName().Name; + hostBuilder.UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName); + + // Light up the GenericWebHostBuilder implementation + if (hostBuilder is ISupportsStartup supportsStartup) + { + return supportsStartup.UseStartup(startupType); + } + return hostBuilder - .UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName) .ConfigureServices(services => { if (typeof(IStartup).GetTypeInfo().IsAssignableFrom(startupType.GetTypeInfo())) @@ -100,6 +113,12 @@ namespace Microsoft.AspNetCore.Hosting /// The . public static IWebHostBuilder UseDefaultServiceProvider(this IWebHostBuilder hostBuilder, Action configure) { + // Light up the GenericWebHostBuilder implementation + if (hostBuilder is ISupportsUseDefaultServiceProvider supportsDefaultServiceProvider) + { + return supportsDefaultServiceProvider.UseDefaultServiceProvider(configure); + } + return hostBuilder.ConfigureServices((context, services) => { var options = new ServiceProviderOptions(); diff --git a/test/Microsoft.AspNetCore.Hosting.Tests/Fakes/GenericWebHost.cs b/test/Microsoft.AspNetCore.Hosting.Tests/Fakes/GenericWebHost.cs new file mode 100644 index 0000000000..d61ce147a7 --- /dev/null +++ b/test/Microsoft.AspNetCore.Hosting.Tests/Fakes/GenericWebHost.cs @@ -0,0 +1,35 @@ +// 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.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace Microsoft.AspNetCore.Hosting.Tests.Fakes +{ + internal class GenericWebHost : IWebHost + { + private readonly IHost _host; + + public GenericWebHost(IHost host) + { + _host = host; + } + + public IFeatureCollection ServerFeatures => Services.GetRequiredService().Features; + + public IServiceProvider Services => _host.Services; + + public void Dispose() => _host.Dispose(); + + public void Start() => _host.Start(); + + public Task StartAsync(CancellationToken cancellationToken = default) => _host.StartAsync(cancellationToken); + + public Task StopAsync(CancellationToken cancellationToken = default) => _host.StopAsync(cancellationToken); + } +} diff --git a/test/Microsoft.AspNetCore.Hosting.Tests/Fakes/GenericWebHostBuilderWrapper.cs b/test/Microsoft.AspNetCore.Hosting.Tests/Fakes/GenericWebHostBuilderWrapper.cs new file mode 100644 index 0000000000..3ff3aeef51 --- /dev/null +++ b/test/Microsoft.AspNetCore.Hosting.Tests/Fakes/GenericWebHostBuilderWrapper.cs @@ -0,0 +1,77 @@ +// 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 Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting.Internal; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace Microsoft.AspNetCore.Hosting.Tests.Fakes +{ + public class GenericWebHostBuilderWrapper : IWebHostBuilder, ISupportsStartup, ISupportsUseDefaultServiceProvider + { + private readonly GenericWebHostBuilder _builder; + private readonly HostBuilder _hostBuilder; + + internal GenericWebHostBuilderWrapper(HostBuilder hostBuilder) + { + _builder = new GenericWebHostBuilder(hostBuilder); + _hostBuilder = hostBuilder; + } + + // This is the only one that doesn't pass through + public IWebHost Build() + { + return new GenericWebHost(_hostBuilder.Build()); + } + + public IWebHostBuilder Configure(Action configure) + { + _builder.Configure(configure); + return this; + } + + public IWebHostBuilder ConfigureAppConfiguration(Action configureDelegate) + { + _builder.ConfigureAppConfiguration(configureDelegate); + return this; + } + + public IWebHostBuilder ConfigureServices(Action configureServices) + { + _builder.ConfigureServices(configureServices); + return this; + } + + public IWebHostBuilder ConfigureServices(Action configureServices) + { + _builder.ConfigureServices(configureServices); + return this; + } + + public string GetSetting(string key) + { + return _builder.GetSetting(key); + } + + public IWebHostBuilder UseDefaultServiceProvider(Action configure) + { + _builder.UseDefaultServiceProvider(configure); + return this; + } + + public IWebHostBuilder UseSetting(string key, string value) + { + _builder.UseSetting(key, value); + return this; + } + + public IWebHostBuilder UseStartup(Type startupType) + { + _builder.UseStartup(startupType); + return this; + } + } +} diff --git a/test/Microsoft.AspNetCore.Hosting.Tests/Fakes/StartupNoServicesNoInterface.cs b/test/Microsoft.AspNetCore.Hosting.Tests/Fakes/StartupNoServicesNoInterface.cs new file mode 100644 index 0000000000..d97cee737a --- /dev/null +++ b/test/Microsoft.AspNetCore.Hosting.Tests/Fakes/StartupNoServicesNoInterface.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; + +namespace Microsoft.AspNetCore.Hosting.Fakes +{ + public class StartupNoServicesNoInterface + { + public void ConfigureServices(IServiceCollection services) + { + + } + + public void Configure(IApplicationBuilder app) + { + + } + } +} diff --git a/test/Microsoft.AspNetCore.Hosting.Tests/Microsoft.AspNetCore.Hosting.Tests.csproj b/test/Microsoft.AspNetCore.Hosting.Tests/Microsoft.AspNetCore.Hosting.Tests.csproj index 5b24d9e604..5f08fb9b6c 100644 --- a/test/Microsoft.AspNetCore.Hosting.Tests/Microsoft.AspNetCore.Hosting.Tests.csproj +++ b/test/Microsoft.AspNetCore.Hosting.Tests/Microsoft.AspNetCore.Hosting.Tests.csproj @@ -10,6 +10,7 @@ + diff --git a/test/Microsoft.AspNetCore.Hosting.Tests/WebHostBuilderTests.cs b/test/Microsoft.AspNetCore.Hosting.Tests/WebHostBuilderTests.cs index c1244e5c8f..876959ddb4 100644 --- a/test/Microsoft.AspNetCore.Hosting.Tests/WebHostBuilderTests.cs +++ b/test/Microsoft.AspNetCore.Hosting.Tests/WebHostBuilderTests.cs @@ -13,10 +13,12 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting.Fakes; using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Hosting.Tests.Fakes; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Testing; @@ -29,22 +31,24 @@ namespace Microsoft.AspNetCore.Hosting { public class WebHostBuilderTests { - [Fact] - public void Build_honors_UseStartup_with_string() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void Build_honors_UseStartup_with_string(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder().UseServer(new TestServer()); + builder = builder.UseServer(new TestServer()); - using (var host = (WebHost)builder.UseStartup("MyStartupAssembly").Build()) + using (var host = builder.UseStartup("MyStartupAssembly").Build()) { - Assert.Equal("MyStartupAssembly", host.Options.ApplicationName); - Assert.Equal("MyStartupAssembly", host.Options.StartupAssembly); + var options = new WebHostOptions(host.Services.GetRequiredService()); + Assert.Equal("MyStartupAssembly", options.ApplicationName); + Assert.Equal("MyStartupAssembly", options.StartupAssembly); } } - [Fact] - public async Task StartupMissing_Fallback() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public async Task StartupMissing_Fallback(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder(); var server = new TestServer(); using (var host = builder.UseServer(server).UseStartup("MissingStartupAssembly").Build()) { @@ -53,10 +57,10 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public async Task StartupStaticCtorThrows_Fallback() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public async Task StartupStaticCtorThrows_Fallback(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder(); var server = new TestServer(); var host = builder.UseServer(server).UseStartup().Build(); using (host) @@ -66,10 +70,10 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public async Task StartupCtorThrows_Fallback() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public async Task StartupCtorThrows_Fallback(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder(); var server = new TestServer(); var host = builder.UseServer(server).UseStartup().Build(); using (host) @@ -79,10 +83,10 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public async Task StartupCtorThrows_TypeLoadException() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public async Task StartupCtorThrows_TypeLoadException(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder(); var server = new TestServer(); var host = builder.UseServer(server).UseStartup().Build(); using (host) @@ -92,10 +96,10 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public async Task IApplicationLifetimeRegisteredEvenWhenStartupCtorThrows_Fallback() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public async Task IApplicationLifetimeRegisteredEvenWhenStartupCtorThrows_Fallback(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder(); var server = new TestServer(); var host = builder.UseServer(server).UseStartup().Build(); using (host) @@ -109,11 +113,12 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public async Task DefaultObjectPoolProvider_IsRegistered() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public async Task DefaultObjectPoolProvider_IsRegistered(IWebHostBuilder builder) { var server = new TestServer(); - var host = CreateWebHostBuilder() + var host = builder .UseServer(server) .Configure(app => { }) .Build(); @@ -124,10 +129,10 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public async Task StartupConfigureServicesThrows_Fallback() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public async Task StartupConfigureServicesThrows_Fallback(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder(); var server = new TestServer(); var host = builder.UseServer(server).UseStartup().Build(); using (host) @@ -137,10 +142,10 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public async Task StartupConfigureThrows_Fallback() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public async Task StartupConfigureThrows_Fallback(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder(); var server = new TestServer(); var host = builder.UseServer(server).UseStartup().Build(); using (host) @@ -150,23 +155,25 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void DefaultCreatesLoggerFactory() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void DefaultCreatesLoggerFactory(IWebHostBuilder builder) { - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .UseServer(new TestServer()) .UseStartup(); - using (var host = (WebHost)hostBuilder.Build()) + using (var host = hostBuilder.Build()) { Assert.NotNull(host.Services.GetService()); } } - [Fact] - public void ConfigureDefaultServiceProvider() + [Theory] + [MemberData(nameof(DefaultWebHostBuilders))] + public void ConfigureDefaultServiceProvider(IWebHostBuilder builder) { - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .UseServer(new TestServer()) .ConfigureServices(s => { @@ -185,11 +192,12 @@ namespace Microsoft.AspNetCore.Hosting Assert.Throws(() => hostBuilder.Build().Start()); } - [Fact] - public void ConfigureDefaultServiceProviderWithContext() + [Theory] + [MemberData(nameof(DefaultWebHostBuilders))] + public void ConfigureDefaultServiceProviderWithContext(IWebHostBuilder builder) { var configurationCallbackCalled = false; - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .UseServer(new TestServer()) .ConfigureServices(s => { @@ -212,11 +220,12 @@ namespace Microsoft.AspNetCore.Hosting Assert.True(configurationCallbackCalled); } - [Fact] - public void MultipleConfigureLoggingInvokedInOrder() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void MultipleConfigureLoggingInvokedInOrder(IWebHostBuilder builder) { var callCount = 0; //Verify ordering - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .ConfigureLogging(loggerFactory => { Assert.Equal(0, callCount++); @@ -234,8 +243,9 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public async Task MultipleStartupAssembliesSpecifiedOnlyAddAssemblyOnce() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public async Task MultipleStartupAssembliesSpecifiedOnlyAddAssemblyOnce(IWebHostBuilder builder) { var provider = new TestLoggerProvider(); var assemblyName = "RandomName"; @@ -246,7 +256,7 @@ namespace Microsoft.AspNetCore.Hosting }; var config = new ConfigurationBuilder().AddInMemoryCollection(data).Build(); - var builder = CreateWebHostBuilder() + builder = builder .UseConfiguration(config) .ConfigureLogging((_, factory) => { @@ -255,7 +265,7 @@ namespace Microsoft.AspNetCore.Hosting .UseServer(new TestServer()); // Verify that there was only one exception throw rather than two. - using (var host = (WebHost)builder.Build()) + using (var host = builder.Build()) { await host.StartAsync(); var context = provider.Sink.Writes.Where(s => s.EventId.Id == LoggerEventIds.HostingStartupAssemblyException); @@ -267,7 +277,7 @@ namespace Microsoft.AspNetCore.Hosting [Fact] public void HostingContextContainsAppConfigurationDuringConfigureLogging() { - var hostBuilder = new WebHostBuilder() + var hostBuilder = CreateWebHostBuilder() .ConfigureAppConfiguration((context, configBuilder) => configBuilder.AddInMemoryCollection( new KeyValuePair[] @@ -287,7 +297,7 @@ namespace Microsoft.AspNetCore.Hosting [Fact] public void HostingContextContainsAppConfigurationDuringConfigureServices() { - var hostBuilder = new WebHostBuilder() + var hostBuilder = CreateWebHostBuilder() .ConfigureAppConfiguration((context, configBuilder) => configBuilder.AddInMemoryCollection( new KeyValuePair[] @@ -304,23 +314,25 @@ namespace Microsoft.AspNetCore.Hosting using (hostBuilder.Build()) { } } - [Fact] - public void ThereIsAlwaysConfiguration() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void ThereIsAlwaysConfiguration(IWebHostBuilder builder) { - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .UseServer(new TestServer()) .UseStartup(); - using (var host = (WebHost)hostBuilder.Build()) + using (var host = hostBuilder.Build()) { Assert.NotNull(host.Services.GetService()); } } - [Fact] - public void ConfigureConfigurationSettingsPropagated() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void ConfigureConfigurationSettingsPropagated(IWebHostBuilder builder) { - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .UseSetting("key1", "value1") .ConfigureAppConfiguration((context, configBuilder) => { @@ -333,10 +345,11 @@ namespace Microsoft.AspNetCore.Hosting using (hostBuilder.Build()) { } } - [Fact] - public void CanConfigureConfigurationAndRetrieveFromDI() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void CanConfigureConfigurationAndRetrieveFromDI(IWebHostBuilder builder) { - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .ConfigureAppConfiguration((_, configBuilder) => { configBuilder @@ -350,7 +363,7 @@ namespace Microsoft.AspNetCore.Hosting .UseServer(new TestServer()) .UseStartup(); - using (var host = (WebHost)hostBuilder.Build()) + using (var host = hostBuilder.Build()) { var config = host.Services.GetService(); Assert.NotNull(config); @@ -358,10 +371,11 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void DoNotCaptureStartupErrorsByDefault() + [Theory] + [MemberData(nameof(DefaultWebHostBuilders))] + public void DoNotCaptureStartupErrorsByDefault(IWebHostBuilder builder) { - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .UseServer(new TestServer()) .UseStartup(); @@ -386,10 +400,11 @@ namespace Microsoft.AspNetCore.Hosting Assert.True(service.Disposed); } - [Fact] - public void CaptureStartupErrorsHonored() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void CaptureStartupErrorsHonored(IWebHostBuilder builder) { - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .CaptureStartupErrors(false) .UseServer(new TestServer()) .UseStartup(); @@ -398,11 +413,12 @@ namespace Microsoft.AspNetCore.Hosting Assert.Equal("A public method named 'ConfigureProduction' or 'Configure' could not be found in the 'Microsoft.AspNetCore.Hosting.Fakes.StartupBoom' type.", exception.Message); } - [Fact] - public void ConfigureServices_CanBeCalledMultipleTimes() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void ConfigureServices_CanBeCalledMultipleTimes(IWebHostBuilder builder) { var callCount = 0; // Verify ordering - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .UseServer(new TestServer()) .ConfigureServices(services => { @@ -425,23 +441,26 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void CodeBasedSettingsCodeBasedOverride() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void CodeBasedSettingsCodeBasedOverride(IWebHostBuilder builder) { - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .UseSetting(WebHostDefaults.EnvironmentKey, "EnvA") .UseSetting(WebHostDefaults.EnvironmentKey, "EnvB") .UseServer(new TestServer()) .UseStartup(); - using (var host = (WebHost)hostBuilder.Build()) + using (var host = hostBuilder.Build()) { - Assert.Equal("EnvB", host.Options.Environment); + var options = new WebHostOptions(host.Services.GetRequiredService()); + Assert.Equal("EnvB", options.Environment); } } - [Fact] - public void CodeBasedSettingsConfigBasedOverride() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void CodeBasedSettingsConfigBasedOverride(IWebHostBuilder builder) { var settings = new Dictionary { @@ -452,20 +471,22 @@ namespace Microsoft.AspNetCore.Hosting .AddInMemoryCollection(settings) .Build(); - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .UseSetting(WebHostDefaults.EnvironmentKey, "EnvA") .UseConfiguration(config) .UseServer(new TestServer()) .UseStartup(); - using (var host = (WebHost)hostBuilder.Build()) + using (var host = hostBuilder.Build()) { - Assert.Equal("EnvB", host.Options.Environment); + var options = new WebHostOptions(host.Services.GetRequiredService()); + Assert.Equal("EnvB", options.Environment); } } - [Fact] - public void ConfigBasedSettingsCodeBasedOverride() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void ConfigBasedSettingsCodeBasedOverride(IWebHostBuilder builder) { var settings = new Dictionary { @@ -476,20 +497,22 @@ namespace Microsoft.AspNetCore.Hosting .AddInMemoryCollection(settings) .Build(); - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .UseConfiguration(config) .UseSetting(WebHostDefaults.EnvironmentKey, "EnvB") .UseServer(new TestServer()) .UseStartup(); - using (var host = (WebHost)hostBuilder.Build()) + using (var host = hostBuilder.Build()) { - Assert.Equal("EnvB", host.Options.Environment); + var options = new WebHostOptions(host.Services.GetRequiredService()); + Assert.Equal("EnvB", options.Environment); } } - [Fact] - public void ConfigBasedSettingsConfigBasedOverride() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void ConfigBasedSettingsConfigBasedOverride(IWebHostBuilder builder) { var settings = new Dictionary { @@ -509,33 +532,35 @@ namespace Microsoft.AspNetCore.Hosting .AddInMemoryCollection(overrideSettings) .Build(); - var hostBuilder = new WebHostBuilder() + var hostBuilder = builder .UseConfiguration(config) .UseConfiguration(overrideConfig) .UseServer(new TestServer()) .UseStartup(); - using (var host = (WebHost)hostBuilder.Build()) + using (var host = hostBuilder.Build()) { - Assert.Equal("EnvB", host.Options.Environment); + var options = new WebHostOptions(host.Services.GetRequiredService()); + Assert.Equal("EnvB", options.Environment); } } - [Fact] - public void UseEnvironmentIsNotOverriden() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void UseEnvironmentIsNotOverriden(IWebHostBuilder builder) { var vals = new Dictionary { { "ENV", "Dev" }, }; - var builder = new ConfigurationBuilder() + var configBuilder = new ConfigurationBuilder() .AddInMemoryCollection(vals); - var config = builder.Build(); + var config = configBuilder.Build(); var expected = "MY_TEST_ENVIRONMENT"; - using (var host = new WebHostBuilder() + using (var host = builder .UseConfiguration(config) .UseEnvironment(expected) .UseServer(new TestServer()) @@ -547,19 +572,20 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void BuildAndDispose() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void BuildAndDispose(IWebHostBuilder builder) { var vals = new Dictionary { { "ENV", "Dev" }, }; - var builder = new ConfigurationBuilder() + var configBuilder = new ConfigurationBuilder() .AddInMemoryCollection(vals); - var config = builder.Build(); + var config = configBuilder.Build(); var expected = "MY_TEST_ENVIRONMENT"; - using (var host = new WebHostBuilder() + using (var host = builder .UseConfiguration(config) .UseEnvironment(expected) .UseServer(new TestServer()) @@ -567,18 +593,19 @@ namespace Microsoft.AspNetCore.Hosting .Build()) { } } - [Fact] - public void UseBasePathConfiguresBasePath() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void UseBasePathConfiguresBasePath(IWebHostBuilder builder) { var vals = new Dictionary { { "ENV", "Dev" }, }; - var builder = new ConfigurationBuilder() + var configBuilder = new ConfigurationBuilder() .AddInMemoryCollection(vals); - var config = builder.Build(); + var config = configBuilder.Build(); - using (var host = new WebHostBuilder() + using (var host = builder .UseConfiguration(config) .UseContentRoot("/") .UseServer(new TestServer()) @@ -590,10 +617,11 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void RelativeContentRootIsResolved() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void RelativeContentRootIsResolved(IWebHostBuilder builder) { - using (var host = new WebHostBuilder() + using (var host = builder .UseContentRoot("testroot") .UseServer(new TestServer()) .UseStartup("Microsoft.AspNetCore.Hosting.Tests") @@ -610,10 +638,11 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void DefaultContentRootIsApplicationBasePath() + [Theory] + [MemberData(nameof(DefaultWebHostBuilders))] + public void DefaultContentRootIsApplicationBasePath(IWebHostBuilder builder) { - using (var host = new WebHostBuilder() + using (var host = builder .UseServer(new TestServer()) .UseStartup("Microsoft.AspNetCore.Hosting.Tests") .Build()) @@ -624,22 +653,23 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void DefaultWebHostBuilderWithNoStartupThrows() + [Theory] + [MemberData(nameof(DefaultWebHostBuilders))] + public void DefaultWebHostBuilderWithNoStartupThrows(IWebHostBuilder builder) { - var host = new WebHostBuilder() + var host = builder .UseServer(new TestServer()); - var ex = Assert.Throws(() => host.Build()); + var ex = Assert.Throws(() => host.Build().Start()); - Assert.Contains("No startup configured.", ex.Message); + Assert.Contains("No application configured.", ex.Message); } - [Fact] - public void DefaultApplicationNameWithUseStartupOfString() + [Theory] + [MemberData(nameof(DefaultWebHostBuilders))] + public void DefaultApplicationNameWithUseStartupOfString(IWebHostBuilder builder) { - var builder = new ConfigurationBuilder(); - using (var host = new WebHostBuilder() + using (var host = builder .UseServer(new TestServer()) .UseStartup(typeof(Startup).Assembly.GetName().Name) .Build()) @@ -651,40 +681,40 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void DefaultApplicationNameWithUseStartupOfT() + [Theory] + [MemberData(nameof(DefaultWebHostBuilders))] + public void DefaultApplicationNameWithUseStartupOfT(IWebHostBuilder builder) { - var builder = new ConfigurationBuilder(); - using (var host = new WebHostBuilder() + using (var host = builder .UseServer(new TestServer()) - .UseStartup() + .UseStartup() .Build()) { var hostingEnv = host.Services.GetService(); var hostingEnv2 = host.Services.GetService(); - Assert.Equal(typeof(StartupNoServices).Assembly.GetName().Name, hostingEnv.ApplicationName); - Assert.Equal(typeof(StartupNoServices).Assembly.GetName().Name, hostingEnv2.ApplicationName); + Assert.Equal(typeof(StartupNoServicesNoInterface).Assembly.GetName().Name, hostingEnv.ApplicationName); + Assert.Equal(typeof(StartupNoServicesNoInterface).Assembly.GetName().Name, hostingEnv2.ApplicationName); } } - [Fact] - public void DefaultApplicationNameWithUseStartupOfType() + [Theory] + [MemberData(nameof(DefaultWebHostBuilders))] + public void DefaultApplicationNameWithUseStartupOfType(IWebHostBuilder builder) { - var builder = new ConfigurationBuilder(); - var host = new WebHostBuilder() + var host = builder .UseServer(new TestServer()) - .UseStartup(typeof(StartupNoServices)) + .UseStartup(typeof(StartupNoServicesNoInterface)) .Build(); var hostingEnv = host.Services.GetService(); - Assert.Equal(typeof(StartupNoServices).Assembly.GetName().Name, hostingEnv.ApplicationName); + Assert.Equal(typeof(StartupNoServicesNoInterface).Assembly.GetName().Name, hostingEnv.ApplicationName); } - [Fact] - public void DefaultApplicationNameWithConfigure() + [Theory] + [MemberData(nameof(DefaultWebHostBuilders))] + public void DefaultApplicationNameWithConfigure(IWebHostBuilder builder) { - var builder = new ConfigurationBuilder(); - using (var host = new WebHostBuilder() + using (var host = builder .UseServer(new TestServer()) .Configure(app => { }) .Build()) @@ -696,10 +726,11 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void Configure_SupportsNonStaticMethodDelegate() + [Theory] + [MemberData(nameof(DefaultWebHostBuilders))] + public void Configure_SupportsNonStaticMethodDelegate(IWebHostBuilder builder) { - using (var host = new WebHostBuilder() + using (var host = builder .UseServer(new TestServer()) .Configure(app => { }) .Build()) @@ -709,10 +740,11 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void Configure_SupportsStaticMethodDelegate() + [Theory] + [MemberData(nameof(DefaultWebHostBuilders))] + public void Configure_SupportsStaticMethodDelegate(IWebHostBuilder builder) { - using (var host = new WebHostBuilder() + using (var host = builder .UseServer(new TestServer()) .Configure(StaticConfigureMethod) .Build()) @@ -736,11 +768,11 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void Build_DoesNotOverrideILoggerFactorySetByConfigureServices() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void Build_DoesNotOverrideILoggerFactorySetByConfigureServices(IWebHostBuilder builder) { var factory = new DisposableLoggerFactory(); - var builder = CreateWebHostBuilder(); var server = new TestServer(); using (var host = builder.UseServer(server) @@ -753,10 +785,11 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void Build_RunsHostingStartupAssembliesIfSpecified() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void Build_RunsHostingStartupAssembliesIfSpecified(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder() + builder = builder .CaptureStartupErrors(false) .UseSetting(WebHostDefaults.HostingStartupAssembliesKey, typeof(TestStartupAssembly1.TestHostingStartup1).GetTypeInfo().Assembly.FullName) .Configure(app => { }) @@ -768,10 +801,11 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void Build_RunsHostingStartupRunsPrimaryAssemblyFirst() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void Build_RunsHostingStartupRunsPrimaryAssemblyFirst(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder() + builder = builder .CaptureStartupErrors(false) .UseSetting(WebHostDefaults.HostingStartupAssembliesKey, typeof(TestStartupAssembly1.TestHostingStartup1).GetTypeInfo().Assembly.FullName) .Configure(app => { }) @@ -785,31 +819,28 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void Build_RunsHostingStartupAssembliesBeforeApplication() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void Build_RunsHostingStartupAssembliesBeforeApplication(IWebHostBuilder builder) { - var startup = new StartupVerifyServiceA(); var startupAssemblyName = typeof(WebHostBuilderTests).GetTypeInfo().Assembly.GetName().Name; - var builder = CreateWebHostBuilder() + builder = builder .CaptureStartupErrors(false) .UseSetting(WebHostDefaults.HostingStartupAssembliesKey, typeof(WebHostBuilderTests).GetTypeInfo().Assembly.FullName) .UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName) - .ConfigureServices(services => - { - services.AddSingleton(startup); - }) + .UseStartup() .UseServer(new TestServer()); using (var host = builder.Build()) { host.Start(); + var startup = host.Services.GetRequiredService(); Assert.NotNull(startup.ServiceADescriptor); Assert.NotNull(startup.ServiceA); } } - [Fact] public async Task ExternalContainerInstanceCanBeUsedForEverything() { @@ -825,7 +856,7 @@ namespace Microsoft.AspNetCore.Hosting }); }); - var host = new WebHostBuilder() + var host = CreateWebHostBuilder() .UseStartup() .UseServer(new TestServer()) .ConfigureServices(services => @@ -849,9 +880,36 @@ namespace Microsoft.AspNetCore.Hosting } [Fact] - public void Build_HostingStartupAssemblyCanBeExcluded() + public void GenericWebHostThrowsWithIStartup() { - var builder = CreateWebHostBuilder() + var builder = new GenericWebHostBuilderWrapper(new HostBuilder()) + .UseStartup(); + + var exception = Assert.Throws(() => builder.Build()); + Assert.Equal("Microsoft.AspNetCore.Hosting.IStartup isn't supported", exception.Message); + } + + [Fact] + public void GenericWebHostThrowsOnBuild() + { + var exception = Assert.Throws(() => + { + var hostBuilder = new HostBuilder() + .ConfigureWebHost(builder => + { + builder.UseStartup(); + builder.Build(); + }); + }); + + Assert.Equal("Building this implementation of IWebHostBuilder is not supported.", exception.Message); + } + + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void Build_HostingStartupAssemblyCanBeExcluded(IWebHostBuilder builder) + { + builder = builder .CaptureStartupErrors(false) .UseSetting(WebHostDefaults.HostingStartupAssembliesKey, typeof(TestStartupAssembly1.TestHostingStartup1).GetTypeInfo().Assembly.FullName) .UseSetting(WebHostDefaults.HostingStartupExcludeAssembliesKey, typeof(TestStartupAssembly1.TestHostingStartup1).GetTypeInfo().Assembly.FullName) @@ -865,10 +923,11 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void Build_ConfigureLoggingInHostingStartupWorks() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void Build_ConfigureLoggingInHostingStartupWorks(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder() + builder = builder .CaptureStartupErrors(false) .Configure(app => { @@ -878,7 +937,7 @@ namespace Microsoft.AspNetCore.Hosting }) .UseServer(new TestServer()); - using (var host = (WebHost)builder.Build()) + using (var host = builder.Build()) { host.Start(); var sink = host.Services.GetRequiredService(); @@ -886,25 +945,27 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void Build_ConfigureAppConfigurationInHostingStartupWorks() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void Build_ConfigureAppConfigurationInHostingStartupWorks(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder() + builder = builder .CaptureStartupErrors(false) .Configure(app => { }) .UseServer(new TestServer()); - using (var host = (WebHost)builder.Build()) + using (var host = builder.Build()) { var configuration = host.Services.GetRequiredService(); Assert.Equal("value", configuration["testhostingstartup:config"]); } } - [Fact] - public void Build_DoesRunHostingStartupFromPrimaryAssemblyEvenIfNotSpecified() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void Build_DoesRunHostingStartupFromPrimaryAssemblyEvenIfNotSpecified(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder() + builder = builder .Configure(app => { }) .UseServer(new TestServer()); @@ -914,10 +975,11 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void Build_HostingStartupFromPrimaryAssemblyCanBeDisabled() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void Build_HostingStartupFromPrimaryAssemblyCanBeDisabled(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder() + builder = builder .UseSetting(WebHostDefaults.PreventHostingStartupKey, "true") .Configure(app => { }) .UseServer(new TestServer()); @@ -928,10 +990,11 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void Build_DoesntThrowIfUnloadableAssemblyNameInHostingStartupAssemblies() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void Build_DoesntThrowIfUnloadableAssemblyNameInHostingStartupAssemblies(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder() + builder = builder .CaptureStartupErrors(false) .UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "SomeBogusName") .Configure(app => { }) @@ -943,11 +1006,12 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public async Task Build_DoesNotThrowIfUnloadableAssemblyNameInHostingStartupAssembliesAndCaptureStartupErrorsTrue() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public async Task Build_DoesNotThrowIfUnloadableAssemblyNameInHostingStartupAssembliesAndCaptureStartupErrorsTrue(IWebHostBuilder builder) { var provider = new TestLoggerProvider(); - var builder = CreateWebHostBuilder() + builder = builder .ConfigureLogging((_, factory) => { factory.AddProvider(provider); @@ -965,10 +1029,11 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void StartupErrorsAreLoggedIfCaptureStartupErrorsIsTrue() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void StartupErrorsAreLoggedIfCaptureStartupErrorsIsTrue(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder() + builder = builder .CaptureStartupErrors(true) .Configure(app => { @@ -976,7 +1041,7 @@ namespace Microsoft.AspNetCore.Hosting }) .UseServer(new TestServer()); - using (var host = (WebHost)builder.Build()) + using (var host = builder.Build()) { host.Start(); var sink = host.Services.GetRequiredService(); @@ -984,12 +1049,13 @@ namespace Microsoft.AspNetCore.Hosting } } - [Fact] - public void StartupErrorsAreLoggedIfCaptureStartupErrorsIsFalse() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void StartupErrorsAreLoggedIfCaptureStartupErrorsIsFalse(IWebHostBuilder builder) { ITestSink testSink = null; - var builder = CreateWebHostBuilder() + builder = builder .CaptureStartupErrors(false) .Configure(app => { @@ -1017,21 +1083,52 @@ namespace Microsoft.AspNetCore.Hosting Assert.Throws(() => new HostingStartupAttribute(typeof(WebHostTests))); } - [Fact] - public void UseShutdownTimeoutConfiguresShutdownTimeout() + [Theory] + [MemberData(nameof(DefaultWebHostBuildersWithConfig))] + public void UseShutdownTimeoutConfiguresShutdownTimeout(IWebHostBuilder builder) { - var builder = CreateWebHostBuilder() + builder = builder .CaptureStartupErrors(false) .UseShutdownTimeout(TimeSpan.FromSeconds(102)) .Configure(app => { }) .UseServer(new TestServer()); - using (var host = (WebHost)builder.Build()) + using (var host = builder.Build()) { - Assert.Equal(TimeSpan.FromSeconds(102), host.Options.ShutdownTimeout); + var options = new WebHostOptions(host.Services.GetRequiredService()); + Assert.Equal(TimeSpan.FromSeconds(102), options.ShutdownTimeout); } } + [Theory] + [MemberData(nameof(DefaultWebHostBuilders))] + public async Task StartupFiltersDoNotRunIfNotApplicationConfigured(IWebHostBuilder builder) + { + var hostBuilder = builder + .ConfigureServices(services => + { + services.AddSingleton(); + }) + .UseServer(new TestServer()); + + var exception = await Assert.ThrowsAsync(async () => + { + var host = hostBuilder.Build(); + var filter = (MyStartupFilter)host.Services.GetServices().FirstOrDefault(s => s is MyStartupFilter); + Assert.NotNull(filter); + try + { + await host.StartAsync(); + } + finally + { + Assert.False(filter.Executed); + } + }); + + Assert.Contains("No application configured.", exception.Message); + } + private static void StaticConfigureMethod(IApplicationBuilder app) { } private IWebHostBuilder CreateWebHostBuilder() @@ -1044,9 +1141,37 @@ namespace Microsoft.AspNetCore.Hosting var builder = new ConfigurationBuilder() .AddInMemoryCollection(vals); var config = builder.Build(); + return new WebHostBuilder().UseConfiguration(config); } + public static TheoryData DefaultWebHostBuilders => new TheoryData + { + new WebHostBuilder(), + new GenericWebHostBuilderWrapper(new HostBuilder()) + }; + + public static TheoryData DefaultWebHostBuildersWithConfig + { + get + { + var vals = new Dictionary + { + { "DetailedErrors", "true" }, + { "captureStartupErrors", "true" } + }; + + var builder = new ConfigurationBuilder() + .AddInMemoryCollection(vals); + var config = builder.Build(); + + return new TheoryData { + new WebHostBuilder().UseConfiguration(config), + new GenericWebHostBuilderWrapper(new HostBuilder()).UseConfiguration(config) + }; + } + } + private async Task AssertResponseContains(RequestDelegate app, string expectedText) { var httpContext = new DefaultHttpContext(); @@ -1057,6 +1182,17 @@ namespace Microsoft.AspNetCore.Hosting Assert.Contains(expectedText, bodyText); } + private class MyStartupFilter : IStartupFilter + { + public bool Executed { get; set; } + + public Action Configure(Action next) + { + Executed = true; + return next; + } + } + private class TestServer : IServer { IFeatureCollection IServer.Features { get; } @@ -1132,17 +1268,17 @@ namespace Microsoft.AspNetCore.Hosting } } - internal class StartupVerifyServiceA : IStartup + internal class StartupVerifyServiceA { internal ServiceA ServiceA { get; set; } internal ServiceDescriptor ServiceADescriptor { get; set; } - public IServiceProvider ConfigureServices(IServiceCollection services) + public void ConfigureServices(IServiceCollection services) { - ServiceADescriptor = services.FirstOrDefault(s => s.ServiceType == typeof(ServiceA)); + services.AddSingleton(this); - return services.BuildServiceProvider(); + ServiceADescriptor = services.FirstOrDefault(s => s.ServiceType == typeof(ServiceA)); } public void Configure(IApplicationBuilder app) From f6cda4fab73ff5d4594741cc5b34b58fa3d0e579 Mon Sep 17 00:00:00 2001 From: "Chris Ross (ASP.NET)" Date: Fri, 16 Nov 2018 16:39:50 -0800 Subject: [PATCH 25/26] Make TestServer handle exceptions from OnStarting #1594 --- .../HttpContextBuilder.cs | 11 +++- .../ClientHandlerTests.cs | 57 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.TestHost/HttpContextBuilder.cs b/src/Microsoft.AspNetCore.TestHost/HttpContextBuilder.cs index 6886b1aac4..c576628b65 100644 --- a/src/Microsoft.AspNetCore.TestHost/HttpContextBuilder.cs +++ b/src/Microsoft.AspNetCore.TestHost/HttpContextBuilder.cs @@ -109,7 +109,16 @@ namespace Microsoft.AspNetCore.TestHost if (!_responseFeature.HasStarted) { // Sets HasStarted - await _responseFeature.FireOnSendingHeadersAsync(); + try + { + await _responseFeature.FireOnSendingHeadersAsync(); + } + catch (Exception ex) + { + Abort(ex); + return; + } + // Copy the feature collection so we're not multi-threading on the same collection. var newFeatures = new FeatureCollection(); foreach (var pair in _httpContext.Features) diff --git a/test/Microsoft.AspNetCore.TestHost.Tests/ClientHandlerTests.cs b/test/Microsoft.AspNetCore.TestHost.Tests/ClientHandlerTests.cs index e90a79e97b..7187f493dc 100644 --- a/test/Microsoft.AspNetCore.TestHost.Tests/ClientHandlerTests.cs +++ b/test/Microsoft.AspNetCore.TestHost.Tests/ClientHandlerTests.cs @@ -272,6 +272,63 @@ namespace Microsoft.AspNetCore.TestHost Assert.IsType(ex.GetBaseException()); } + [Fact] + public Task ExceptionFromOnStartingFirstWriteIsReported() + { + var handler = new ClientHandler(PathString.Empty, new DummyApplication(context => + { + context.Response.OnStarting(() => + { + throw new InvalidOperationException(new string('a', 1024 * 32)); + }); + return context.Response.WriteAsync("Hello World"); + })); + var httpClient = new HttpClient(handler); + return Assert.ThrowsAsync(() => httpClient.GetAsync("https://example.com/", + HttpCompletionOption.ResponseHeadersRead)); + } + + [Fact] + public Task ExceptionFromOnStartingWithNoWriteIsReported() + { + var handler = new ClientHandler(PathString.Empty, new DummyApplication(context => + { + context.Response.OnStarting(() => + { + throw new InvalidOperationException(new string('a', 1024 * 32)); + }); + return Task.CompletedTask; + })); + var httpClient = new HttpClient(handler); + return Assert.ThrowsAsync(() => httpClient.GetAsync("https://example.com/", + HttpCompletionOption.ResponseHeadersRead)); + } + + [Fact] + public Task ExceptionFromOnStartingWithErrorHandlerIsReported() + { + var handler = new ClientHandler(PathString.Empty, new DummyApplication(async context => + { + context.Response.OnStarting(() => + { + throw new InvalidOperationException(new string('a', 1024 * 32)); + }); + try + { + await context.Response.WriteAsync("Hello World"); + } + catch (Exception ex) + { + // This is no longer the first write, so it doesn't trigger OnStarting again. + // The exception is large enough that it fills the pipe and stalls. + await context.Response.WriteAsync(ex.ToString()); + } + })); + var httpClient = new HttpClient(handler); + return Assert.ThrowsAsync(() => httpClient.GetAsync("https://example.com/", + HttpCompletionOption.ResponseHeadersRead)); + } + private class DummyApplication : IHttpApplication { RequestDelegate _application; From 241d2c13df468d18149f2245efb0d6dbcfc7a60d Mon Sep 17 00:00:00 2001 From: "Chris Ross (ASP.NET)" Date: Fri, 16 Nov 2018 11:01:01 -0800 Subject: [PATCH 26/26] Add TestServer support for generic WebHost #1583 --- .../HostBuilderTestServerExtensions.cs | 35 +++++++++++ .../TestServer.cs | 49 +++++++++++---- .../WebHostBuilderExtensions.cs | 9 +++ ...ostingAbstractionsHostBuilderExtensions.cs | 18 +++++- ...Microsoft.AspNetCore.TestHost.Tests.csproj | 1 + .../TestServerTests.cs | 62 +++++++++++++++++++ 6 files changed, 160 insertions(+), 14 deletions(-) create mode 100644 src/Microsoft.AspNetCore.TestHost/HostBuilderTestServerExtensions.cs diff --git a/src/Microsoft.AspNetCore.TestHost/HostBuilderTestServerExtensions.cs b/src/Microsoft.AspNetCore.TestHost/HostBuilderTestServerExtensions.cs new file mode 100644 index 0000000000..e52f3d6ab0 --- /dev/null +++ b/src/Microsoft.AspNetCore.TestHost/HostBuilderTestServerExtensions.cs @@ -0,0 +1,35 @@ +// 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.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace Microsoft.AspNetCore.TestHost +{ + public static class HostBuilderTestServerExtensions + { + /// + /// Retrieves the TestServer from the host services. + /// + /// + /// + public static TestServer GetTestServer(this IHost host) + { + return (TestServer)host.Services.GetRequiredService(); + } + + /// + /// Retrieves the test client from the TestServer in the host services. + /// + /// + /// + public static HttpClient GetTestClient(this IHost host) + { + return host.GetTestServer().CreateClient(); + } + } +} diff --git a/src/Microsoft.AspNetCore.TestHost/TestServer.cs b/src/Microsoft.AspNetCore.TestHost/TestServer.cs index 398a575d9d..40a3e63f05 100644 --- a/src/Microsoft.AspNetCore.TestHost/TestServer.cs +++ b/src/Microsoft.AspNetCore.TestHost/TestServer.cs @@ -6,6 +6,7 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; @@ -15,28 +16,48 @@ namespace Microsoft.AspNetCore.TestHost { public class TestServer : IServer { - private const string ServerName = nameof(TestServer); private IWebHost _hostInstance; private bool _disposed = false; private IHttpApplication _application; + /// + /// For use with IHostBuilder or IWebHostBuilder. + /// + public TestServer() + : this(new FeatureCollection()) + { + } + + /// + /// For use with IHostBuilder or IWebHostBuilder. + /// + /// + public TestServer(IFeatureCollection featureCollection) + { + Features = featureCollection ?? throw new ArgumentNullException(nameof(featureCollection)); + } + + /// + /// For use with IWebHostBuilder. + /// + /// public TestServer(IWebHostBuilder builder) : this(builder, new FeatureCollection()) { } + /// + /// For use with IWebHostBuilder. + /// + /// + /// public TestServer(IWebHostBuilder builder, IFeatureCollection featureCollection) + : this(featureCollection) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } - if (featureCollection == null) - { - throw new ArgumentNullException(nameof(featureCollection)); - } - - Features = featureCollection; var host = builder.UseServer(this).Build(); host.StartAsync().GetAwaiter().GetResult(); @@ -49,16 +70,22 @@ namespace Microsoft.AspNetCore.TestHost { get { - return _hostInstance; + return _hostInstance + ?? throw new InvalidOperationException("The TestServer constructor was not called with a IWebHostBuilder so IWebHost is not available."); } } public IFeatureCollection Features { get; } + private IHttpApplication Application + { + get => _application ?? throw new InvalidOperationException("The server has not been started or no web application was configured."); + } + public HttpMessageHandler CreateHandler() { var pathBase = BaseAddress == null ? PathString.Empty : PathString.FromUriComponent(BaseAddress); - return new ClientHandler(pathBase, _application); + return new ClientHandler(pathBase, Application); } public HttpClient CreateClient() @@ -69,7 +96,7 @@ namespace Microsoft.AspNetCore.TestHost public WebSocketClient CreateWebSocketClient() { var pathBase = BaseAddress == null ? PathString.Empty : PathString.FromUriComponent(BaseAddress); - return new WebSocketClient(pathBase, _application); + return new WebSocketClient(pathBase, Application); } /// @@ -93,7 +120,7 @@ namespace Microsoft.AspNetCore.TestHost throw new ArgumentNullException(nameof(configureContext)); } - var builder = new HttpContextBuilder(_application); + var builder = new HttpContextBuilder(Application); builder.Configure(context => { var request = context.Request; diff --git a/src/Microsoft.AspNetCore.TestHost/WebHostBuilderExtensions.cs b/src/Microsoft.AspNetCore.TestHost/WebHostBuilderExtensions.cs index cccf19cdd5..308ac86cd4 100644 --- a/src/Microsoft.AspNetCore.TestHost/WebHostBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.TestHost/WebHostBuilderExtensions.cs @@ -6,12 +6,21 @@ using System.IO; using System.Linq; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting.Internal; +using Microsoft.AspNetCore.Hosting.Server; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.TestHost { public static class WebHostBuilderExtensions { + public static IWebHostBuilder UseTestServer(this IWebHostBuilder builder) + { + return builder.ConfigureServices(services => + { + services.AddSingleton(); + }); + } + public static IWebHostBuilder ConfigureTestServices(this IWebHostBuilder webHostBuilder, Action servicesConfiguration) { if (webHostBuilder == null) diff --git a/src/Microsoft.Extensions.Hosting.Abstractions/HostingAbstractionsHostBuilderExtensions.cs b/src/Microsoft.Extensions.Hosting.Abstractions/HostingAbstractionsHostBuilderExtensions.cs index 8b1c4d3494..b4753d7201 100644 --- a/src/Microsoft.Extensions.Hosting.Abstractions/HostingAbstractionsHostBuilderExtensions.cs +++ b/src/Microsoft.Extensions.Hosting.Abstractions/HostingAbstractionsHostBuilderExtensions.cs @@ -2,20 +2,32 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading; +using System.Threading.Tasks; namespace Microsoft.Extensions.Hosting { public static class HostingAbstractionsHostBuilderExtensions { /// - /// Start the host and listen on the specified urls. + /// Builds and starts the host. /// /// The to start. - /// The . + /// The started . public static IHost Start(this IHostBuilder hostBuilder) + { + return hostBuilder.StartAsync().GetAwaiter().GetResult(); + } + + /// + /// Builds and starts the host. + /// + /// The to start. + /// + /// The started . + public static async Task StartAsync(this IHostBuilder hostBuilder, CancellationToken cancellationToken = default) { var host = hostBuilder.Build(); - host.StartAsync(CancellationToken.None).GetAwaiter().GetResult(); + await host.StartAsync(cancellationToken); return host; } } diff --git a/test/Microsoft.AspNetCore.TestHost.Tests/Microsoft.AspNetCore.TestHost.Tests.csproj b/test/Microsoft.AspNetCore.TestHost.Tests/Microsoft.AspNetCore.TestHost.Tests.csproj index 25b877467c..f62aae9cec 100644 --- a/test/Microsoft.AspNetCore.TestHost.Tests/Microsoft.AspNetCore.TestHost.Tests.csproj +++ b/test/Microsoft.AspNetCore.TestHost.Tests/Microsoft.AspNetCore.TestHost.Tests.csproj @@ -6,6 +6,7 @@ + diff --git a/test/Microsoft.AspNetCore.TestHost.Tests/TestServerTests.cs b/test/Microsoft.AspNetCore.TestHost.Tests/TestServerTests.cs index a4175a75cb..cc789962c7 100644 --- a/test/Microsoft.AspNetCore.TestHost.Tests/TestServerTests.cs +++ b/test/Microsoft.AspNetCore.TestHost.Tests/TestServerTests.cs @@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DiagnosticAdapter; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; using Xunit; @@ -23,6 +24,56 @@ namespace Microsoft.AspNetCore.TestHost { public class TestServerTests { + [Fact] + public async Task GenericRawCreate() + { + var server = new TestServer(); + var host = new HostBuilder() + .ConfigureWebHost(webBuilder => + { + webBuilder + .UseServer(server) + .Configure(app => { }); + }) + .Build(); + await host.StartAsync(); + + var response = await server.CreateClient().GetAsync("/"); + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + } + + [Fact] + public async Task GenericCreateAndStartHost_GetTestServer() + { + var host = await new HostBuilder() + .ConfigureWebHost(webBuilder => + { + webBuilder + .UseTestServer() + .Configure(app => { }); + }) + .StartAsync(); + + var response = await host.GetTestServer().CreateClient().GetAsync("/"); + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + } + + [Fact] + public async Task GenericCreateAndStartHost_GetTestClient() + { + var host = await new HostBuilder() + .ConfigureWebHost(webBuilder => + { + webBuilder + .UseTestServer() + .Configure(app => { }); + }) + .StartAsync(); + + var response = await host.GetTestClient().GetAsync("/"); + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + } + [Fact] public void CreateWithDelegate() { @@ -31,6 +82,17 @@ namespace Microsoft.AspNetCore.TestHost new TestServer(new WebHostBuilder().Configure(app => { })); } + [Fact] + public void CreateWithDelegate_DI() + { + var builder = new WebHostBuilder() + .Configure(app => { }) + .UseTestServer(); + + var host = builder.Build(); + host.Start(); + } + [Fact] public void DoesNotCaptureStartupErrorsByDefault() {