Merge branch 'release/2.2'

This commit is contained in:
Nate McMaster 2018-11-20 09:47:59 -08:00
commit 294b5f2928
No known key found for this signature in database
GPG Key ID: A778D9601BD78810
567 changed files with 86431 additions and 31 deletions

8
.gitmodules vendored
View File

@ -18,14 +18,6 @@
path = modules/Diagnostics
url = https://github.com/aspnet/Diagnostics.git
branch = master
[submodule "modules/Hosting"]
path = modules/Hosting
url = https://github.com/aspnet/Hosting.git
branch = master
[submodule "modules/HttpAbstractions"]
path = modules/HttpAbstractions
url = https://github.com/aspnet/HttpAbstractions.git
branch = master
[submodule "modules/HttpSysServer"]
path = modules/HttpSysServer
url = https://github.com/aspnet/HttpSysServer.git

View File

@ -84,6 +84,8 @@
<IncludeSource>false</IncludeSource>
<IncludeSymbols>true</IncludeSymbols>
<SharedSourceRoot>$(MSBuildThisFileDirectory)src\Shared\</SharedSourceRoot>
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
</PropertyGroup>

View File

@ -31,6 +31,8 @@
<FilesToSign Include="Microsoft.Extensions.FileProviders.Embedded.dll" Certificate="$(AssemblySigningCertName)" Container="Microsoft.AspNetCore.App" />
<FilesToSign Include="Microsoft.Extensions.FileProviders.Physical.dll" Certificate="$(AssemblySigningCertName)" Container="Microsoft.AspNetCore.App" />
<FilesToSign Include="Microsoft.Extensions.FileSystemGlobbing.dll" Certificate="$(AssemblySigningCertName)" Container="Microsoft.AspNetCore.App" />
<FilesToSign Include="Microsoft.Extensions.Hosting.Abstractions.dll" Certificate="$(AssemblySigningCertName)" Container="Microsoft.AspNetCore.App" />
<FilesToSign Include="Microsoft.Extensions.Hosting.dll" Certificate="$(AssemblySigningCertName)" Container="Microsoft.AspNetCore.App" />
<FilesToSign Include="Microsoft.Extensions.Http.dll" Certificate="$(AssemblySigningCertName)" Container="Microsoft.AspNetCore.App" />
<FilesToSign Include="Microsoft.Extensions.Logging.Abstractions.dll" Certificate="$(AssemblySigningCertName)" Container="Microsoft.AspNetCore.App" />
<FilesToSign Include="Microsoft.Extensions.Logging.Configuration.dll" Certificate="$(AssemblySigningCertName)" Container="Microsoft.AspNetCore.App" />

View File

@ -1,6 +1,8 @@
<Project>
<PropertyGroup>
<!-- _ProjectsOnly is for local builds and shouldn't be used on CI. -->
<DisableCodeSigning Condition=" '$(_ProjectsOnly)' == 'true' ">true</DisableCodeSigning>
<CodeSignDependsOn>$(CodeSignDependsOn);CollectFileSignInfo</CodeSignDependsOn>
</PropertyGroup>

View File

@ -19,7 +19,6 @@
<PackageArtifact Include="dotnet-user-secrets" Category="ship" />
<PackageArtifact Include="dotnet-watch" Category="ship" />
<PackageArtifact Include="Internal.AspNetCore.Universe.Lineup" Category="noship" />
<PackageArtifact Include="Internal.WebHostBuilderFactory.Sources" Category="noship" />
<PackageArtifact Include="Microsoft.AspNet.Identity.AspNetCoreCompat" Category="noship" />
<PackageArtifact Include="Microsoft.AspNetCore.ApiAuthorization.IdentityServer" Category="noship" />
<PackageArtifact Include="Microsoft.AspNetCore.App" Category="ship" />
@ -128,7 +127,6 @@
<PackageArtifact Include="Microsoft.AspNetCore.Server.IIS" Category="ship" />
<PackageArtifact Include="Microsoft.AspNetCore.Server.IISIntegration" Category="ship" />
<PackageArtifact Include="Microsoft.AspNetCore.Server.IntegrationTesting.IIS" Category="noship" />
<PackageArtifact Include="Microsoft.AspNetCore.Server.IntegrationTesting" Category="noship" />
<PackageArtifact Include="Microsoft.AspNetCore.Server.Kestrel.Core" Category="ship" />
<PackageArtifact Include="Microsoft.AspNetCore.Server.Kestrel.Https" Category="ship" />
<PackageArtifact Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions" Category="ship" />
@ -164,8 +162,6 @@
<PackageArtifact Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Category="ship" />
<PackageArtifact Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Category="ship" />
<PackageArtifact Include="Microsoft.Extensions.Diagnostics.HealthChecks" Category="ship" />
<PackageArtifact Include="Microsoft.Extensions.Hosting.Abstractions" Category="ship" />
<PackageArtifact Include="Microsoft.Extensions.Hosting" Category="ship" />
<PackageArtifact Include="Microsoft.Extensions.Identity.Core" Category="ship" />
<PackageArtifact Include="Microsoft.Extensions.Identity.Stores" Category="ship" />
<PackageArtifact Include="Microsoft.Extensions.Localization.Abstractions" Category="ship" />

View File

@ -8,8 +8,6 @@
<ItemGroup>
<RepositoryBuildOrder Include="Razor" Order="6" />
<RepositoryBuildOrder Include="HttpAbstractions" Order="6" />
<RepositoryBuildOrder Include="Hosting" Order="7" />
<RepositoryBuildOrder Include="HttpSysServer" Order="8" />
<RepositoryBuildOrder Include="BasicMiddleware" Order="9" />
<RepositoryBuildOrder Include="Antiforgery" Order="10" />
@ -32,6 +30,6 @@
<RepositoryBuildOrder Include="MusicStore" Order="16" RootPath="$(RepositoryRoot)src\MusicStore\" />
<RepositoryBuildOrder Include="SignalR" Order="16" />
<RepositoryBuildOrder Include="AuthSamples" Order="16" RootPath="$(RepositoryRoot)src\AuthSamples\" />
<RepositoryBuildOrder Include="Templating" Order="17" RootPath="$(RepositoryRoot)src\templating\" />
<RepositoryBuildOrder Include="templating" Order="17" RootPath="$(RepositoryRoot)src\templating\" />
</ItemGroup>
</Project>

View File

@ -69,6 +69,8 @@
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
<MicrosoftExtensionsHostingAbstractionsPackageVersion>3.0.0-alpha1-10742</MicrosoftExtensionsHostingAbstractionsPackageVersion>
<MicrosoftExtensionsHostingPackageVersion>3.0.0-alpha1-10742</MicrosoftExtensionsHostingPackageVersion>
<MicrosoftExtensionsHttpPackageVersion>3.0.0-alpha1-10742</MicrosoftExtensionsHttpPackageVersion>
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
<MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>

View File

@ -45,6 +45,8 @@
<ExternalDependency Include="Microsoft.Extensions.FileProviders.Physical" Version="$(MicrosoftExtensionsFileProvidersPhysicalPackageVersion)" />
<ExternalDependency Include="Microsoft.Extensions.FileSystemGlobbing" Version="$(MicrosoftExtensionsFileSystemGlobbingPackageVersion)" />
<ExternalDependency Include="Microsoft.Extensions.HashCodeCombiner.Sources" Version="$(MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion)" />
<ExternalDependency Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(MicrosoftExtensionsHostingAbstractionsPackageVersion)" />
<ExternalDependency Include="Microsoft.Extensions.Hosting" Version="$(MicrosoftExtensionsHostingPackageVersion)" />
<ExternalDependency Include="Microsoft.Extensions.Http" Version="$(MicrosoftExtensionsHttpPackageVersion)" />
<ExternalDependency Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftExtensionsLoggingAbstractionsPackageVersion)" />
<ExternalDependency Include="Microsoft.Extensions.Logging.AzureAppServices" Version="$(MicrosoftExtensionsLoggingAzureAppServicesPackageVersion)" />
@ -82,8 +84,6 @@
<ExternalDependency Include="Microsoft.EntityFrameworkCore.SqlServer" Version="$(MicrosoftEntityFrameworkCoreSqlServerPackageVersion)" />
<ExternalDependency Include="Microsoft.EntityFrameworkCore.Tools" Version="$(MicrosoftEntityFrameworkCoreToolsPackageVersion)" />
<ExternalDependency Include="Microsoft.EntityFrameworkCore" Version="$(MicrosoftEntityFrameworkCorePackageVersion)" />
<ExternalDependency Include="Microsoft.Extensions.Buffers.Testing.Sources" Version="$(MicrosoftExtensionsBuffersTestingSourcesPackageVersion)" />
<ExternalDependency Include="Microsoft.Extensions.Buffers.MemoryPool.Sources" Version="$(MicrosoftExtensionsBuffersMemoryPoolSourcesPackageVersion)" />
</ItemGroup>
<ItemGroup>

View File

@ -63,6 +63,8 @@
<ProjectToBuild Include="
$(RepositoryRoot)src\Features\JsonPatch\**\*.*proj;
$(RepositoryRoot)src\DataProtection\**\*.*proj;
$(RepositoryRoot)src\Hosting\**\*.*proj;
$(RepositoryRoot)src\Http\**\*.*proj;
$(RepositoryRoot)src\Html\**\*.*proj;
$(RepositoryRoot)src\Servers\**\*.*proj;
$(RepositoryRoot)src\Tools\**\*.*proj;

View File

@ -42,8 +42,6 @@
<Repository Include="BasicMiddleware" />
<Repository Include="CORS" />
<Repository Include="Diagnostics" />
<Repository Include="Hosting" />
<Repository Include="HttpAbstractions" />
<Repository Include="HttpSysServer" />
<Repository Include="Identity" />
<Repository Include="IISIntegration" RootPath="$(RepositoryRoot)src\IISIntegration\" />
@ -58,7 +56,7 @@
<Repository Include="Session" />
<Repository Include="SignalR" />
<Repository Include="StaticFiles" />
<Repository Include="Templating" RootPath="$(RepositoryRoot)src\templating\" PatchPolicy="AlwaysUpdateAndCascadeVersions" />
<Repository Include="templating" RootPath="$(RepositoryRoot)src\templating\" PatchPolicy="AlwaysUpdateAndCascadeVersions" />
<!-- Test-only repos -->
<Repository Include="AuthSamples" RootPath="$(RepositoryRoot)src\AuthSamples\" PatchPolicy="AlwaysUpdateAndCascadeVersions" />

View File

@ -4,6 +4,24 @@
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<AspNetCoreBaselineVersion>2.2.0</AspNetCoreBaselineVersion>
</PropertyGroup>
<!-- Package: Microsoft.AspNetCore.Authentication.Abstractions-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Authentication.Abstractions' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Authentication.Abstractions' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Options" Version="[2.2.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Authentication.Core-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Authentication.Core' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Authentication.Core' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.AspNetCore.Authentication.Abstractions" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.AspNetCore.Http" Version="[2.2.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Connections.Abstractions-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Connections.Abstractions' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
@ -96,6 +114,53 @@
<BaselinePackageReference Include="System.Security.Cryptography.Xml" Version="[4.5.0, )" />
<BaselinePackageReference Include="System.Security.Principal.Windows" Version="[4.5.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Hosting.Abstractions-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting.Abstractions' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting.Abstractions' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="[2.2.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Hosting.Server.Abstractions-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting.Server.Abstractions' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting.Server.Abstractions' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Features" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="[2.2.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Hosting.WindowsServices-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting.WindowsServices' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting.WindowsServices' AND '$(TargetFramework)' == 'net461' ">
<BaselinePackageReference Include="Microsoft.AspNetCore.Hosting" Version="[2.2.0, )" />
</ItemGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting.WindowsServices' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.AspNetCore.Hosting" Version="[2.2.0, )" />
<BaselinePackageReference Include="System.ServiceProcess.ServiceController" Version="[4.5.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Hosting-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.AspNetCore.Http" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Configuration" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.DependencyInjection" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Logging" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Options" Version="[2.2.0, )" />
<BaselinePackageReference Include="System.Diagnostics.DiagnosticSource" Version="[4.5.0, )" />
<BaselinePackageReference Include="System.Reflection.Metadata" Version="[1.6.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Html.Abstractions-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Html.Abstractions' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
@ -103,6 +168,42 @@
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Html.Abstractions' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="System.Text.Encodings.Web" Version="[4.5.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Http.Abstractions-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http.Abstractions' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http.Abstractions' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Features" Version="[2.2.0, )" />
<BaselinePackageReference Include="System.Text.Encodings.Web" Version="[4.5.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Http.Extensions-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http.Extensions' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http.Extensions' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Net.Http.Headers" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.FileProviders.Abstractions" Version="[2.2.0, )" />
<BaselinePackageReference Include="System.Buffers" Version="[4.5.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Http.Features-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http.Features' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http.Features' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.Extensions.Primitives" Version="[2.2.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Http-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Net.Http.Headers" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.ObjectPool" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Options" Version="[2.2.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.JsonPatch-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.JsonPatch' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
@ -111,6 +212,13 @@
<BaselinePackageReference Include="Microsoft.CSharp" Version="[4.5.0, )" />
<BaselinePackageReference Include="Newtonsoft.Json" Version="[11.0.2, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Owin-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Owin' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Owin' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.AspNetCore.Http" Version="[2.2.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Server.Kestrel.Core-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Server.Kestrel.Core' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
@ -199,6 +307,14 @@
<BaselinePackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" Version="[2.2.0, )" />
<BaselinePackageReference Include="Microsoft.AspNetCore.Hosting" Version="[2.2.0, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.TestHost-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.TestHost' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.TestHost' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.AspNetCore.Hosting" Version="[2.2.0, )" />
<BaselinePackageReference Include="System.IO.Pipelines" Version="[4.5.2, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.WebSockets-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.WebSockets' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
@ -209,4 +325,20 @@
<BaselinePackageReference Include="Microsoft.Extensions.Options" Version="[2.2.0, )" />
<BaselinePackageReference Include="System.Net.WebSockets.WebSocketProtocol" Version="[4.5.1, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.WebUtilities-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.WebUtilities' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.WebUtilities' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.Net.Http.Headers" Version="[2.2.0, )" />
<BaselinePackageReference Include="System.Text.Encodings.Web" Version="[4.5.0, )" />
</ItemGroup>
<!-- Package: Microsoft.Net.Http.Headers-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.Net.Http.Headers' ">
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.Net.Http.Headers' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.Extensions.Primitives" Version="[2.2.0, )" />
<BaselinePackageReference Include="System.Buffers" Version="[4.5.0, )" />
</ItemGroup>
</Project>

View File

@ -17,6 +17,7 @@
<LatestPackageReference Include="Microsoft.EntityFrameworkCore" Version="$(MicrosoftEntityFrameworkCorePackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.ActivatorUtilities.Sources" Version="$(MicrosoftExtensionsActivatorUtilitiesSourcesPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.ClosedGenericMatcher.Sources" Version="$(MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.CopyOnWriteDictionary.Sources" Version="$(MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.CommandLineUtils.Sources" Version="$(MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="$(MicrosoftExtensionsConfigurationBinderPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="$(MicrosoftExtensionsConfigurationCommandLinePackageVersion)" />
@ -26,17 +27,24 @@
<LatestPackageReference Include="Microsoft.Extensions.Configuration" Version="$(MicrosoftExtensionsConfigurationPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.DiagnosticAdapter" Version="$(MicrosoftExtensionsDiagnosticAdapterPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Hosting" Version="$(MicrosoftExtensionsHostingPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftExtensionsLoggingAbstractionsPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="$(MicrosoftExtensionsFileProvidersEmbeddedPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Process.Sources" Version="$(MicrosoftExtensionsProcessSourcesPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.RazorViews.Sources" Version="$(MicrosoftExtensionsRazorViewsSourcesPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.StackTrace.Sources" Version="$(MicrosoftExtensionsStackTraceSourcesPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.TypeNameHelper.Sources" Version="$(MicrosoftExtensionsTypeNameHelperSourcesPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.WebEncoders.Sources" Version="$(MicrosoftExtensionsWebEncodersSourcesPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.WebEncoders" Version="$(MicrosoftExtensionsWebEncodersPackageVersion)" />
<LatestPackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="$(MicrosoftIdentityModelClientsActiveDirectoryPackageVersion)" />
<LatestPackageReference Include="Microsoft.Internal.AspNetCore.H2Spec.All" Version="$(MicrosoftInternalAspNetCoreH2SpecAllPackageVersion)" />
<LatestPackageReference Include="Microsoft.Win32.Registry" Version="$(MicrosoftWin32RegistryPackageVersion)" />
<LatestPackageReference Include="Microsoft.NETCore.Windows.ApiSets" Version="$(MicrosoftNETCoreWindowsApiSetsPackageVersion)" />
<LatestPackageReference Include="System.Data.SqlClient" Version="$(SystemDataSqlClientPackageVersion)" />
<LatestPackageReference Include="System.IO.Pipelines" Version="$(SystemIOPipelinesPackageVersion)" />
<LatestPackageReference Include="System.Memory" Version="$(SystemMemoryPackageVersion)" />
@ -65,6 +73,8 @@
<LatestPackageReference Include="WindowsAzure.Storage" Version="8.1.4" />
<LatestPackageReference Include="Selenium.WebDriver.ChromeDriver" Version="2.43.0" />
<LatestPackageReference Include="Selenium.WebDriver" Version="3.12.1" />
<LatestPackageReference Include="Serilog.Extensions.Logging" Version="$(SerilogExtensionsLoggingPackageVersion)" />
<LatestPackageReference Include="Serilog.Sinks.File" Version="$(SerilogSinksFilePackageVersion)" />
<LatestPackageReference Include="Utf8Json" Version="1.3.7" />
<LatestPackageReference Include="xunit.abstractions" Version="2.0.1" />
<LatestPackageReference Include="xunit.analyzers" Version="0.10.0" />

View File

@ -12,6 +12,21 @@
<ProjectReferenceProvider Include="Microsoft.AspNetCore.DataProtection.Extensions" ProjectPath="$(RepositoryRoot)src\DataProtection\Extensions\src\Microsoft.AspNetCore.DataProtection.Extensions.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" ProjectPath="$(RepositoryRoot)src\DataProtection\StackExchangeRedis\src\Microsoft.AspNetCore.DataProtection.StackExchangeRedis.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.DataProtection.SystemWeb" ProjectPath="$(RepositoryRoot)src\DataProtection\SystemWeb\src\Microsoft.AspNetCore.DataProtection.SystemWeb.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Hosting.Abstractions" ProjectPath="$(RepositoryRoot)src\Hosting\Abstractions\src\Microsoft.AspNetCore.Hosting.Abstractions.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Hosting" ProjectPath="$(RepositoryRoot)src\Hosting\Hosting\src\Microsoft.AspNetCore.Hosting.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" ProjectPath="$(RepositoryRoot)src\Hosting\Server.Abstractions\src\Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Server.IntegrationTesting" ProjectPath="$(RepositoryRoot)src\Hosting\Server.IntegrationTesting\src\Microsoft.AspNetCore.Server.IntegrationTesting.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.TestHost" ProjectPath="$(RepositoryRoot)src\Hosting\TestHost\src\Microsoft.AspNetCore.TestHost.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Hosting.WindowsServices" ProjectPath="$(RepositoryRoot)src\Hosting\WindowsServices\src\Microsoft.AspNetCore.Hosting.WindowsServices.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Authentication.Abstractions" ProjectPath="$(RepositoryRoot)src\Http\Authentication.Abstractions\src\Microsoft.AspNetCore.Authentication.Abstractions.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Authentication.Core" ProjectPath="$(RepositoryRoot)src\Http\Authentication.Core\src\Microsoft.AspNetCore.Authentication.Core.csproj" />
<ProjectReferenceProvider Include="Microsoft.Net.Http.Headers" ProjectPath="$(RepositoryRoot)src\Http\Headers\src\Microsoft.Net.Http.Headers.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Http.Abstractions" ProjectPath="$(RepositoryRoot)src\Http\Http.Abstractions\src\Microsoft.AspNetCore.Http.Abstractions.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Http.Extensions" ProjectPath="$(RepositoryRoot)src\Http\Http.Extensions\src\Microsoft.AspNetCore.Http.Extensions.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Http.Features" ProjectPath="$(RepositoryRoot)src\Http\Http.Features\src\Microsoft.AspNetCore.Http.Features.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Http" ProjectPath="$(RepositoryRoot)src\Http\Http\src\Microsoft.AspNetCore.Http.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Owin" ProjectPath="$(RepositoryRoot)src\Http\Owin\src\Microsoft.AspNetCore.Owin.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.WebUtilities" ProjectPath="$(RepositoryRoot)src\Http\WebUtilities\src\Microsoft.AspNetCore.WebUtilities.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Html.Abstractions" ProjectPath="$(RepositoryRoot)src\Html\Abstractions\src\Microsoft.AspNetCore.Html.Abstractions.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Connections.Abstractions" ProjectPath="$(RepositoryRoot)src\Servers\Connections.Abstractions\src\Microsoft.AspNetCore.Connections.Abstractions.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Server.Kestrel.Core" ProjectPath="$(RepositoryRoot)src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj" />

View File

@ -1,5 +1,5 @@
<!--
This file is temporary until aspnet/Hosting, Diagnostics, StaticFiles, and HttpAbstractions are merged into this repo.
This file is temporary until aspnet/Diagnostics and StaticFiles are merged into this repo.
This is required to provide dependencies for samples and tests.
-->
<Project>
@ -7,13 +7,5 @@ This is required to provide dependencies for samples and tests.
<LatestPackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="3.0.0-alpha1-10727" />
<LatestPackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="3.0.0-alpha1-10727" />
<LatestPackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="3.0.0-alpha1-10727" />
<LatestPackageReference Include="Microsoft.AspNetCore.Hosting" Version="3.0.0-alpha1-10727" />
<LatestPackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="3.0.0-alpha1-10727" />
<LatestPackageReference Include="Microsoft.AspNetCore.Http.Features" Version="3.0.0-alpha1-10727" />
<LatestPackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="3.0.0-alpha1-10727" />
<LatestPackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="3.0.0-alpha1-10727" />
<LatestPackageReference Include="Microsoft.AspNetCore.Http" Version="3.0.0-alpha1-10727" />
<LatestPackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="3.0.0-alpha1-10727" />
<LatestPackageReference Include="Microsoft.Net.Http.Headers" Version="3.0.0-alpha1-10727" />
</ItemGroup>
</Project>

View File

@ -3,6 +3,8 @@
<Package Id="dotnet-sql-cache" Version="2.2.0" />
<Package Id="dotnet-user-secrets" Version="2.2.0" />
<Package Id="dotnet-watch" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Core" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Connections.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Cryptography.Internal" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="2.2.0" />
@ -14,13 +16,25 @@
<Package Id="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.SystemWeb" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.DataProtection" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Hosting.WindowsServices" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Hosting" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Html.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Http.Features" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Http" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.JsonPatch" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Owin" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Core" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.TestHost" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.WebSockets" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
<Package Id="Microsoft.Net.Http.Headers" Version="2.2.0" />
</Baseline>

@ -1 +0,0 @@
Subproject commit 241d2c13df468d18149f2245efb0d6dbcfc7a60d

@ -1 +0,0 @@
Subproject commit bc7092a32b1943c7f17439e419d3f66cd94ce9bd

View File

@ -0,0 +1,15 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Hosting
{
/// <summary>
/// Commonly used environment names.
/// </summary>
public static class EnvironmentName
{
public static readonly string Development = "Development";
public static readonly string Staging = "Staging";
public static readonly string Production = "Production";
}
}

View File

@ -0,0 +1,197 @@
// 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.Globalization;
using System.Linq;
using System.Threading;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting
{
public static class HostingAbstractionsWebHostBuilderExtensions
{
private static readonly string ServerUrlsSeparator = ";";
/// <summary>
/// Use the given configuration settings on the web host.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="configuration">The <see cref="IConfiguration"/> containing settings to be used.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseConfiguration(this IWebHostBuilder hostBuilder, IConfiguration configuration)
{
foreach (var setting in configuration.AsEnumerable())
{
hostBuilder.UseSetting(setting.Key, setting.Value);
}
return hostBuilder;
}
/// <summary>
/// Set whether startup errors should be captured in the configuration settings of the web host.
/// When enabled, startup exceptions will be caught and an error page will be returned. If disabled, startup exceptions will be propagated.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="captureStartupErrors"><c>true</c> to use startup error page; otherwise <c>false</c>.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder CaptureStartupErrors(this IWebHostBuilder hostBuilder, bool captureStartupErrors)
{
return hostBuilder.UseSetting(WebHostDefaults.CaptureStartupErrorsKey, captureStartupErrors ? "true" : "false");
}
/// <summary>
/// Specify the assembly containing the startup type to be used by the web host.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="startupAssemblyName">The name of the assembly containing the startup type.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseStartup(this IWebHostBuilder hostBuilder, string startupAssemblyName)
{
if (startupAssemblyName == null)
{
throw new ArgumentNullException(nameof(startupAssemblyName));
}
return hostBuilder
.UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName)
.UseSetting(WebHostDefaults.StartupAssemblyKey, startupAssemblyName);
}
/// <summary>
/// Specify the server to be used by the web host.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="server">The <see cref="IServer"/> to be used.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseServer(this IWebHostBuilder hostBuilder, IServer server)
{
if (server == null)
{
throw new ArgumentNullException(nameof(server));
}
return hostBuilder.ConfigureServices(services =>
{
// It would be nicer if this was transient but we need to pass in the
// factory instance directly
services.AddSingleton(server);
});
}
/// <summary>
/// Specify the environment to be used by the web host.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="environment">The environment to host the application in.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseEnvironment(this IWebHostBuilder hostBuilder, string environment)
{
if (environment == null)
{
throw new ArgumentNullException(nameof(environment));
}
return hostBuilder.UseSetting(WebHostDefaults.EnvironmentKey, environment);
}
/// <summary>
/// Specify the content root directory to be used by the web host.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="contentRoot">Path to root directory of the application.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseContentRoot(this IWebHostBuilder hostBuilder, string contentRoot)
{
if (contentRoot == null)
{
throw new ArgumentNullException(nameof(contentRoot));
}
return hostBuilder.UseSetting(WebHostDefaults.ContentRootKey, contentRoot);
}
/// <summary>
/// Specify the webroot directory to be used by the web host.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="webRoot">Path to the root directory used by the web server.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseWebRoot(this IWebHostBuilder hostBuilder, string webRoot)
{
if (webRoot == null)
{
throw new ArgumentNullException(nameof(webRoot));
}
return hostBuilder.UseSetting(WebHostDefaults.WebRootKey, webRoot);
}
/// <summary>
/// Specify the urls the web host will listen on.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="urls">The urls the hosted application will listen on.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseUrls(this IWebHostBuilder hostBuilder, params string[] urls)
{
if (urls == null)
{
throw new ArgumentNullException(nameof(urls));
}
return hostBuilder.UseSetting(WebHostDefaults.ServerUrlsKey, string.Join(ServerUrlsSeparator, urls));
}
/// <summary>
/// Indicate whether the host should listen on the URLs configured on the <see cref="IWebHostBuilder"/>
/// instead of those configured on the <see cref="IServer"/>.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="preferHostingUrls"><c>true</c> to prefer URLs configured on the <see cref="IWebHostBuilder"/>; otherwise <c>false</c>.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder PreferHostingUrls(this IWebHostBuilder hostBuilder, bool preferHostingUrls)
{
return hostBuilder.UseSetting(WebHostDefaults.PreferHostingUrlsKey, preferHostingUrls ? "true" : "false");
}
/// <summary>
/// Specify if startup status messages should be suppressed.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="suppressStatusMessages"><c>true</c> to suppress writing of hosting startup status messages; otherwise <c>false</c>.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder SuppressStatusMessages(this IWebHostBuilder hostBuilder, bool suppressStatusMessages)
{
return hostBuilder.UseSetting(WebHostDefaults.SuppressStatusMessagesKey, suppressStatusMessages ? "true" : "false");
}
/// <summary>
/// Specify the amount of time to wait for the web host to shutdown.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="timeout">The amount of time to wait for server shutdown.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseShutdownTimeout(this IWebHostBuilder hostBuilder, TimeSpan timeout)
{
return hostBuilder.UseSetting(WebHostDefaults.ShutdownTimeoutKey, ((int)timeout.TotalSeconds).ToString(CultureInfo.InvariantCulture));
}
/// <summary>
/// Start the web host and listen on the specified urls.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to start.</param>
/// <param name="urls">The urls the hosted application will listen on.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHost Start(this IWebHostBuilder hostBuilder, params string[] urls)
{
var host = hostBuilder.UseUrls(urls).Build();
host.StartAsync(CancellationToken.None).GetAwaiter().GetResult();
return host;
}
}
}

View File

@ -0,0 +1,80 @@
// 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.IO;
namespace Microsoft.AspNetCore.Hosting
{
/// <summary>
/// Extension methods for <see cref="IHostingEnvironment"/>.
/// </summary>
public static class HostingEnvironmentExtensions
{
/// <summary>
/// Checks if the current hosting environment name is <see cref="EnvironmentName.Development"/>.
/// </summary>
/// <param name="hostingEnvironment">An instance of <see cref="IHostingEnvironment"/>.</param>
/// <returns>True if the environment name is <see cref="EnvironmentName.Development"/>, otherwise false.</returns>
public static bool IsDevelopment(this IHostingEnvironment hostingEnvironment)
{
if (hostingEnvironment == null)
{
throw new ArgumentNullException(nameof(hostingEnvironment));
}
return hostingEnvironment.IsEnvironment(EnvironmentName.Development);
}
/// <summary>
/// Checks if the current hosting environment name is <see cref="EnvironmentName.Staging"/>.
/// </summary>
/// <param name="hostingEnvironment">An instance of <see cref="IHostingEnvironment"/>.</param>
/// <returns>True if the environment name is <see cref="EnvironmentName.Staging"/>, otherwise false.</returns>
public static bool IsStaging(this IHostingEnvironment hostingEnvironment)
{
if (hostingEnvironment == null)
{
throw new ArgumentNullException(nameof(hostingEnvironment));
}
return hostingEnvironment.IsEnvironment(EnvironmentName.Staging);
}
/// <summary>
/// Checks if the current hosting environment name is <see cref="EnvironmentName.Production"/>.
/// </summary>
/// <param name="hostingEnvironment">An instance of <see cref="IHostingEnvironment"/>.</param>
/// <returns>True if the environment name is <see cref="EnvironmentName.Production"/>, otherwise false.</returns>
public static bool IsProduction(this IHostingEnvironment hostingEnvironment)
{
if (hostingEnvironment == null)
{
throw new ArgumentNullException(nameof(hostingEnvironment));
}
return hostingEnvironment.IsEnvironment(EnvironmentName.Production);
}
/// <summary>
/// Compares the current hosting environment name against the specified value.
/// </summary>
/// <param name="hostingEnvironment">An instance of <see cref="IHostingEnvironment"/>.</param>
/// <param name="environmentName">Environment name to validate against.</param>
/// <returns>True if the specified name is the same as the current environment, otherwise false.</returns>
public static bool IsEnvironment(
this IHostingEnvironment hostingEnvironment,
string environmentName)
{
if (hostingEnvironment == null)
{
throw new ArgumentNullException(nameof(hostingEnvironment));
}
return string.Equals(
hostingEnvironment.EnvironmentName,
environmentName,
StringComparison.OrdinalIgnoreCase);
}
}
}

View File

@ -0,0 +1,40 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Reflection;
namespace Microsoft.AspNetCore.Hosting
{
/// <summary>
/// Marker attribute indicating an implementation of <see cref="IHostingStartup"/> that will be loaded and executed when building an <see cref="IWebHost"/>.
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = true)]
public sealed class HostingStartupAttribute : Attribute
{
/// <summary>
/// Constructs the <see cref="HostingStartupAttribute"/> with the specified type.
/// </summary>
/// <param name="hostingStartupType">A type that implements <see cref="IHostingStartup"/>.</param>
public HostingStartupAttribute(Type hostingStartupType)
{
if (hostingStartupType == null)
{
throw new ArgumentNullException(nameof(hostingStartupType));
}
if (!typeof(IHostingStartup).GetTypeInfo().IsAssignableFrom(hostingStartupType.GetTypeInfo()))
{
throw new ArgumentException($@"""{hostingStartupType}"" does not implement {typeof(IHostingStartup)}.", nameof(hostingStartupType));
}
HostingStartupType = hostingStartupType;
}
/// <summary>
/// The implementation of <see cref="IHostingStartup"/> that should be loaded when
/// starting an application.
/// </summary>
public Type HostingStartupType { get; }
}
}

View File

@ -0,0 +1,37 @@
// 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
{
/// <summary>
/// Allows consumers to perform cleanup during a graceful shutdown.
/// </summary>
public interface IApplicationLifetime
{
/// <summary>
/// Triggered when the application host has fully started and is about to wait
/// for a graceful shutdown.
/// </summary>
CancellationToken ApplicationStarted { get; }
/// <summary>
/// Triggered when the application host is performing a graceful shutdown.
/// Requests may still be in flight. Shutdown will block until this event completes.
/// </summary>
CancellationToken ApplicationStopping { get; }
/// <summary>
/// Triggered when the application host is performing a graceful shutdown.
/// All requests should be complete at this point. Shutdown will block
/// until this event completes.
/// </summary>
CancellationToken ApplicationStopped { get; }
/// <summary>
/// Requests termination of the current application.
/// </summary>
void StopApplication();
}
}

View File

@ -0,0 +1,45 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Extensions.FileProviders;
namespace Microsoft.AspNetCore.Hosting
{
/// <summary>
/// Provides information about the web hosting environment an application is running in.
/// </summary>
public interface IHostingEnvironment
{
/// <summary>
/// Gets or sets the name of the environment. The host automatically sets this property to the value
/// of the "ASPNETCORE_ENVIRONMENT" environment variable, or "environment" as specified in any other configuration source.
/// </summary>
string EnvironmentName { get; set; }
/// <summary>
/// Gets or sets the name of the application. This property is automatically set by the host to the assembly containing
/// the application entry point.
/// </summary>
string ApplicationName { get; set; }
/// <summary>
/// Gets or sets the absolute path to the directory that contains the web-servable application content files.
/// </summary>
string WebRootPath { get; set; }
/// <summary>
/// Gets or sets an <see cref="IFileProvider"/> pointing at <see cref="WebRootPath"/>.
/// </summary>
IFileProvider WebRootFileProvider { get; set; }
/// <summary>
/// Gets or sets the absolute path to the directory that contains the application content files.
/// </summary>
string ContentRootPath { get; set; }
/// <summary>
/// Gets or sets an <see cref="IFileProvider"/> pointing at <see cref="ContentRootPath"/>.
/// </summary>
IFileProvider ContentRootFileProvider { get; set; }
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Hosting
{
/// <summary>
/// Represents platform specific configuration that will be applied to a <see cref="IWebHostBuilder"/> when building an <see cref="IWebHost"/>.
/// </summary>
public interface IHostingStartup
{
/// <summary>
/// Configure the <see cref="IWebHostBuilder"/>.
/// </summary>
/// <remarks>
/// Configure is intended to be called before user code, allowing a user to overwrite any changes made.
/// </remarks>
/// <param name="builder"></param>
void Configure(IWebHostBuilder builder);
}
}

View File

@ -0,0 +1,16 @@
// 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.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting
{
public interface IStartup
{
IServiceProvider ConfigureServices(IServiceCollection services);
void Configure(IApplicationBuilder app);
}
}

View File

@ -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.AspNetCore.Builder;
namespace Microsoft.AspNetCore.Hosting
{
public interface IStartupFilter
{
Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next);
}
}

View File

@ -0,0 +1,43 @@
// 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.Http.Features;
namespace Microsoft.AspNetCore.Hosting
{
/// <summary>
/// Represents a configured web host.
/// </summary>
public interface IWebHost : IDisposable
{
/// <summary>
/// The <see cref="IFeatureCollection"/> exposed by the configured server.
/// </summary>
IFeatureCollection ServerFeatures { get; }
/// <summary>
/// The <see cref="IServiceProvider"/> for the host.
/// </summary>
IServiceProvider Services { get; }
/// <summary>
/// Starts listening on the configured addresses.
/// </summary>
void Start();
/// <summary>
/// Starts listening on the configured addresses.
/// </summary>
Task StartAsync(CancellationToken cancellationToken = default);
/// <summary>
/// Attempt to gracefully stop the host.
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task StopAsync(CancellationToken cancellationToken = default);
}
}

View File

@ -0,0 +1,63 @@
// 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.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Hosting
{
/// <summary>
/// A builder for <see cref="IWebHost"/>.
/// </summary>
public interface IWebHostBuilder
{
/// <summary>
/// Builds an <see cref="IWebHost"/> which hosts a web application.
/// </summary>
IWebHost Build();
/// <summary>
/// Adds a delegate for configuring the <see cref="IConfigurationBuilder"/> that will construct an <see cref="IConfiguration"/>.
/// </summary>
/// <param name="configureDelegate">The delegate for configuring the <see cref="IConfigurationBuilder" /> that will be used to construct an <see cref="IConfiguration" />.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
/// <remarks>
/// The <see cref="IConfiguration"/> and <see cref="ILoggerFactory"/> on the <see cref="WebHostBuilderContext"/> are uninitialized at this stage.
/// The <see cref="IConfigurationBuilder"/> is pre-populated with the settings of the <see cref="IWebHostBuilder"/>.
/// </remarks>
IWebHostBuilder ConfigureAppConfiguration(Action<WebHostBuilderContext, IConfigurationBuilder> configureDelegate);
/// <summary>
/// Adds a delegate for configuring additional services for the host or web application. This may be called
/// multiple times.
/// </summary>
/// <param name="configureServices">A delegate for configuring the <see cref="IServiceCollection"/>.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
IWebHostBuilder ConfigureServices(Action<IServiceCollection> configureServices);
/// <summary>
/// Adds a delegate for configuring additional services for the host or web application. This may be called
/// multiple times.
/// </summary>
/// <param name="configureServices">A delegate for configuring the <see cref="IServiceCollection"/>.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
IWebHostBuilder ConfigureServices(Action<WebHostBuilderContext, IServiceCollection> configureServices);
/// <summary>
/// Get the setting value from the configuration.
/// </summary>
/// <param name="key">The key of the setting to look up.</param>
/// <returns>The value the setting currently contains.</returns>
string GetSetting(string key);
/// <summary>
/// Add or replace a setting in the configuration.
/// </summary>
/// <param name="key">The key of the setting to add or replace.</param>
/// <param name="value">The value of the setting to add or replace.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
IWebHostBuilder UseSetting(string key, string value);
}
}

View File

@ -0,0 +1,16 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Hosting.Internal
{
/// <summary>
/// This API supports the ASP.NET Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public interface IStartupConfigureContainerFilter<TContainerBuilder>
{
Action<TContainerBuilder> ConfigureContainer(Action<TContainerBuilder> container);
}
}

View File

@ -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.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting.Internal
{
/// <summary>
/// This API supports the ASP.NET Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public interface IStartupConfigureServicesFilter
{
Action<IServiceCollection> ConfigureServices(Action<IServiceCollection> next);
}
}

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>ASP.NET Core hosting and startup abstractions for web applications.</Description>
<TargetFramework>netstandard2.0</TargetFramework>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;hosting</PackageTags>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" />
<Reference Include="Microsoft.AspNetCore.Http.Abstractions" />
<Reference Include="Microsoft.Extensions.Hosting.Abstractions" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Extensions.Configuration;
namespace Microsoft.AspNetCore.Hosting
{
/// <summary>
/// Context containing the common services on the <see cref="IWebHost" />. Some properties may be null until set by the <see cref="IWebHost" />.
/// </summary>
public class WebHostBuilderContext
{
/// <summary>
/// The <see cref="IHostingEnvironment" /> initialized by the <see cref="IWebHost" />.
/// </summary>
public IHostingEnvironment HostingEnvironment { get; set; }
/// <summary>
/// The <see cref="IConfiguration" /> containing the merged configuration of the application and the <see cref="IWebHost" />.
/// </summary>
public IConfiguration Configuration { get; set; }
}
}

View File

@ -0,0 +1,25 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Hosting
{
public static class WebHostDefaults
{
public static readonly string ApplicationKey = "applicationName";
public static readonly string StartupAssemblyKey = "startupAssembly";
public static readonly string HostingStartupAssembliesKey = "hostingStartupAssemblies";
public static readonly string HostingStartupExcludeAssembliesKey = "hostingStartupExcludeAssemblies";
public static readonly string DetailedErrorsKey = "detailedErrors";
public static readonly string EnvironmentKey = "environment";
public static readonly string WebRootKey = "webroot";
public static readonly string CaptureStartupErrorsKey = "captureStartupErrors";
public static readonly string ServerUrlsKey = "urls";
public static readonly string ContentRootKey = "contentRoot";
public static readonly string PreferHostingUrlsKey = "preferHostingUrls";
public static readonly string PreventHostingStartupKey = "preventHostingStartup";
public static readonly string SuppressStatusMessagesKey = "suppressStatusMessages";
public static readonly string ShutdownTimeoutKey = "shutdownTimeoutSeconds";
}
}

View File

@ -0,0 +1,947 @@
{
"AssemblyIdentity": "Microsoft.AspNetCore.Hosting.Abstractions, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
"Types": [
{
"Name": "Microsoft.AspNetCore.Hosting.EnvironmentName",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Field",
"Name": "Development",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "Staging",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "Production",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "UseConfiguration",
"Parameters": [
{
"Name": "hostBuilder",
"Type": "Microsoft.AspNetCore.Hosting.IWebHostBuilder"
},
{
"Name": "configuration",
"Type": "Microsoft.Extensions.Configuration.IConfiguration"
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "CaptureStartupErrors",
"Parameters": [
{
"Name": "hostBuilder",
"Type": "Microsoft.AspNetCore.Hosting.IWebHostBuilder"
},
{
"Name": "captureStartupErrors",
"Type": "System.Boolean"
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "UseStartup",
"Parameters": [
{
"Name": "hostBuilder",
"Type": "Microsoft.AspNetCore.Hosting.IWebHostBuilder"
},
{
"Name": "startupAssemblyName",
"Type": "System.String"
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "UseServer",
"Parameters": [
{
"Name": "hostBuilder",
"Type": "Microsoft.AspNetCore.Hosting.IWebHostBuilder"
},
{
"Name": "server",
"Type": "Microsoft.AspNetCore.Hosting.Server.IServer"
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "UseEnvironment",
"Parameters": [
{
"Name": "hostBuilder",
"Type": "Microsoft.AspNetCore.Hosting.IWebHostBuilder"
},
{
"Name": "environment",
"Type": "System.String"
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "UseContentRoot",
"Parameters": [
{
"Name": "hostBuilder",
"Type": "Microsoft.AspNetCore.Hosting.IWebHostBuilder"
},
{
"Name": "contentRoot",
"Type": "System.String"
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "UseWebRoot",
"Parameters": [
{
"Name": "hostBuilder",
"Type": "Microsoft.AspNetCore.Hosting.IWebHostBuilder"
},
{
"Name": "webRoot",
"Type": "System.String"
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "UseUrls",
"Parameters": [
{
"Name": "hostBuilder",
"Type": "Microsoft.AspNetCore.Hosting.IWebHostBuilder"
},
{
"Name": "urls",
"Type": "System.String[]",
"IsParams": true
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "PreferHostingUrls",
"Parameters": [
{
"Name": "hostBuilder",
"Type": "Microsoft.AspNetCore.Hosting.IWebHostBuilder"
},
{
"Name": "preferHostingUrls",
"Type": "System.Boolean"
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "UseShutdownTimeout",
"Parameters": [
{
"Name": "hostBuilder",
"Type": "Microsoft.AspNetCore.Hosting.IWebHostBuilder"
},
{
"Name": "timeout",
"Type": "System.TimeSpan"
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Start",
"Parameters": [
{
"Name": "hostBuilder",
"Type": "Microsoft.AspNetCore.Hosting.IWebHostBuilder"
},
{
"Name": "urls",
"Type": "System.String[]",
"IsParams": true
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHost",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Hosting.HostingEnvironmentExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "IsDevelopment",
"Parameters": [
{
"Name": "hostingEnvironment",
"Type": "Microsoft.AspNetCore.Hosting.IHostingEnvironment"
}
],
"ReturnType": "System.Boolean",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "IsStaging",
"Parameters": [
{
"Name": "hostingEnvironment",
"Type": "Microsoft.AspNetCore.Hosting.IHostingEnvironment"
}
],
"ReturnType": "System.Boolean",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "IsProduction",
"Parameters": [
{
"Name": "hostingEnvironment",
"Type": "Microsoft.AspNetCore.Hosting.IHostingEnvironment"
}
],
"ReturnType": "System.Boolean",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "IsEnvironment",
"Parameters": [
{
"Name": "hostingEnvironment",
"Type": "Microsoft.AspNetCore.Hosting.IHostingEnvironment"
},
{
"Name": "environmentName",
"Type": "System.String"
}
],
"ReturnType": "System.Boolean",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Hosting.HostingStartupAttribute",
"Visibility": "Public",
"Kind": "Class",
"Sealed": true,
"BaseType": "System.Attribute",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_HostingStartupType",
"Parameters": [],
"ReturnType": "System.Type",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "hostingStartupType",
"Type": "System.Type"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Hosting.IApplicationLifetime",
"Visibility": "Public",
"Kind": "Interface",
"Abstract": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_ApplicationStarted",
"Parameters": [],
"ReturnType": "System.Threading.CancellationToken",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_ApplicationStopping",
"Parameters": [],
"ReturnType": "System.Threading.CancellationToken",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_ApplicationStopped",
"Parameters": [],
"ReturnType": "System.Threading.CancellationToken",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "StopApplication",
"Parameters": [],
"ReturnType": "System.Void",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Hosting.IHostingEnvironment",
"Visibility": "Public",
"Kind": "Interface",
"Abstract": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_EnvironmentName",
"Parameters": [],
"ReturnType": "System.String",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_EnvironmentName",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_ApplicationName",
"Parameters": [],
"ReturnType": "System.String",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_ApplicationName",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_WebRootPath",
"Parameters": [],
"ReturnType": "System.String",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_WebRootPath",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_WebRootFileProvider",
"Parameters": [],
"ReturnType": "Microsoft.Extensions.FileProviders.IFileProvider",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_WebRootFileProvider",
"Parameters": [
{
"Name": "value",
"Type": "Microsoft.Extensions.FileProviders.IFileProvider"
}
],
"ReturnType": "System.Void",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_ContentRootPath",
"Parameters": [],
"ReturnType": "System.String",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_ContentRootPath",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_ContentRootFileProvider",
"Parameters": [],
"ReturnType": "Microsoft.Extensions.FileProviders.IFileProvider",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_ContentRootFileProvider",
"Parameters": [
{
"Name": "value",
"Type": "Microsoft.Extensions.FileProviders.IFileProvider"
}
],
"ReturnType": "System.Void",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Hosting.IHostingStartup",
"Visibility": "Public",
"Kind": "Interface",
"Abstract": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Configure",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Hosting.IWebHostBuilder"
}
],
"ReturnType": "System.Void",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Hosting.IStartup",
"Visibility": "Public",
"Kind": "Interface",
"Abstract": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "ConfigureServices",
"Parameters": [
{
"Name": "services",
"Type": "Microsoft.Extensions.DependencyInjection.IServiceCollection"
}
],
"ReturnType": "System.IServiceProvider",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Configure",
"Parameters": [
{
"Name": "app",
"Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder"
}
],
"ReturnType": "System.Void",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Hosting.IStartupFilter",
"Visibility": "Public",
"Kind": "Interface",
"Abstract": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Configure",
"Parameters": [
{
"Name": "next",
"Type": "System.Action<Microsoft.AspNetCore.Builder.IApplicationBuilder>"
}
],
"ReturnType": "System.Action<Microsoft.AspNetCore.Builder.IApplicationBuilder>",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Hosting.IWebHost",
"Visibility": "Public",
"Kind": "Interface",
"Abstract": true,
"ImplementedInterfaces": [
"System.IDisposable"
],
"Members": [
{
"Kind": "Method",
"Name": "get_ServerFeatures",
"Parameters": [],
"ReturnType": "Microsoft.AspNetCore.Http.Features.IFeatureCollection",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_Services",
"Parameters": [],
"ReturnType": "System.IServiceProvider",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Start",
"Parameters": [],
"ReturnType": "System.Void",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "StartAsync",
"Parameters": [
{
"Name": "cancellationToken",
"Type": "System.Threading.CancellationToken",
"DefaultValue": "default(System.Threading.CancellationToken)"
}
],
"ReturnType": "System.Threading.Tasks.Task",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "StopAsync",
"Parameters": [
{
"Name": "cancellationToken",
"Type": "System.Threading.CancellationToken",
"DefaultValue": "default(System.Threading.CancellationToken)"
}
],
"ReturnType": "System.Threading.Tasks.Task",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"Visibility": "Public",
"Kind": "Interface",
"Abstract": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Build",
"Parameters": [],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHost",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "ConfigureAppConfiguration",
"Parameters": [
{
"Name": "configureDelegate",
"Type": "System.Action<Microsoft.AspNetCore.Hosting.WebHostBuilderContext, Microsoft.Extensions.Configuration.IConfigurationBuilder>"
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "ConfigureServices",
"Parameters": [
{
"Name": "configureServices",
"Type": "System.Action<Microsoft.Extensions.DependencyInjection.IServiceCollection>"
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "ConfigureServices",
"Parameters": [
{
"Name": "configureServices",
"Type": "System.Action<Microsoft.AspNetCore.Hosting.WebHostBuilderContext, Microsoft.Extensions.DependencyInjection.IServiceCollection>"
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "GetSetting",
"Parameters": [
{
"Name": "key",
"Type": "System.String"
}
],
"ReturnType": "System.String",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "UseSetting",
"Parameters": [
{
"Name": "key",
"Type": "System.String"
},
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Hosting.WebHostBuilderContext",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_HostingEnvironment",
"Parameters": [],
"ReturnType": "Microsoft.AspNetCore.Hosting.IHostingEnvironment",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_HostingEnvironment",
"Parameters": [
{
"Name": "value",
"Type": "Microsoft.AspNetCore.Hosting.IHostingEnvironment"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_Configuration",
"Parameters": [],
"ReturnType": "Microsoft.Extensions.Configuration.IConfiguration",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_Configuration",
"Parameters": [
{
"Name": "value",
"Type": "Microsoft.Extensions.Configuration.IConfiguration"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Hosting.WebHostDefaults",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Field",
"Name": "ApplicationKey",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "StartupAssemblyKey",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "HostingStartupAssembliesKey",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "DetailedErrorsKey",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "EnvironmentKey",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "WebRootKey",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "CaptureStartupErrorsKey",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "ServerUrlsKey",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "ContentRootKey",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "PreferHostingUrlsKey",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "PreventHostingStartupKey",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "ShutdownTimeoutKey",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
}
]
}

View File

@ -0,0 +1,25 @@
// 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.Builder.Internal;
using Microsoft.AspNetCore.Http.Features;
namespace Microsoft.AspNetCore.Hosting.Builder
{
public class ApplicationBuilderFactory : IApplicationBuilderFactory
{
private readonly IServiceProvider _serviceProvider;
public ApplicationBuilderFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IApplicationBuilder CreateBuilder(IFeatureCollection serverFeatures)
{
return new ApplicationBuilder(_serviceProvider, serverFeatures);
}
}
}

View File

@ -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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http.Features;
namespace Microsoft.AspNetCore.Hosting.Builder
{
public interface IApplicationBuilderFactory
{
IApplicationBuilder CreateBuilder(IFeatureCollection serverFeatures);
}
}

View File

@ -0,0 +1,114 @@
// 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.Threading;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Hosting.Internal
{
/// <summary>
/// Allows consumers to perform cleanup during a graceful shutdown.
/// </summary>
public class ApplicationLifetime : IApplicationLifetime, Extensions.Hosting.IApplicationLifetime
{
private readonly CancellationTokenSource _startedSource = new CancellationTokenSource();
private readonly CancellationTokenSource _stoppingSource = new CancellationTokenSource();
private readonly CancellationTokenSource _stoppedSource = new CancellationTokenSource();
private readonly ILogger<ApplicationLifetime> _logger;
public ApplicationLifetime(ILogger<ApplicationLifetime> logger)
{
_logger = logger;
}
/// <summary>
/// Triggered when the application host has fully started and is about to wait
/// for a graceful shutdown.
/// </summary>
public CancellationToken ApplicationStarted => _startedSource.Token;
/// <summary>
/// Triggered when the application host is performing a graceful shutdown.
/// Request may still be in flight. Shutdown will block until this event completes.
/// </summary>
public CancellationToken ApplicationStopping => _stoppingSource.Token;
/// <summary>
/// Triggered when the application host is performing a graceful shutdown.
/// All requests should be complete at this point. Shutdown will block
/// until this event completes.
/// </summary>
public CancellationToken ApplicationStopped => _stoppedSource.Token;
/// <summary>
/// Signals the ApplicationStopping event and blocks until it completes.
/// </summary>
public void StopApplication()
{
// Lock on CTS to synchronize multiple calls to StopApplication. This guarantees that the first call
// to StopApplication and its callbacks run to completion before subsequent calls to StopApplication,
// which will no-op since the first call already requested cancellation, get a chance to execute.
lock (_stoppingSource)
{
try
{
ExecuteHandlers(_stoppingSource);
}
catch (Exception ex)
{
_logger.ApplicationError(LoggerEventIds.ApplicationStoppingException,
"An error occurred stopping the application",
ex);
}
}
}
/// <summary>
/// Signals the ApplicationStarted event and blocks until it completes.
/// </summary>
public void NotifyStarted()
{
try
{
ExecuteHandlers(_startedSource);
}
catch (Exception ex)
{
_logger.ApplicationError(LoggerEventIds.ApplicationStartupException,
"An error occurred starting the application",
ex);
}
}
/// <summary>
/// Signals the ApplicationStopped event and blocks until it completes.
/// </summary>
public void NotifyStopped()
{
try
{
ExecuteHandlers(_stoppedSource);
}
catch (Exception ex)
{
_logger.ApplicationError(LoggerEventIds.ApplicationStoppedException,
"An error occurred stopping the application",
ex);
}
}
private void ExecuteHandlers(CancellationTokenSource cancel)
{
// Noop if this is already cancelled
if (cancel.IsCancellationRequested)
{
return;
}
// Run the cancellation token callbacks
cancel.Cancel(throwOnFirstException: false);
}
}
}

View File

@ -0,0 +1,20 @@
// 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
{
public class AutoRequestServicesStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return builder =>
{
builder.UseMiddleware<RequestServicesContainerMiddleware>();
next(builder);
};
}
}
}

View File

@ -0,0 +1,59 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class ConfigureBuilder
{
public ConfigureBuilder(MethodInfo configure)
{
MethodInfo = configure;
}
public MethodInfo MethodInfo { get; }
public Action<IApplicationBuilder> Build(object instance) => builder => Invoke(instance, builder);
private void Invoke(object instance, IApplicationBuilder builder)
{
// Create a scope for Configure, this allows creating scoped dependencies
// without the hassle of manually creating a scope.
using (var scope = builder.ApplicationServices.CreateScope())
{
var serviceProvider = scope.ServiceProvider;
var parameterInfos = MethodInfo.GetParameters();
var parameters = new object[parameterInfos.Length];
for (var index = 0; index < parameterInfos.Length; index++)
{
var parameterInfo = parameterInfos[index];
if (parameterInfo.ParameterType == typeof(IApplicationBuilder))
{
parameters[index] = builder;
}
else
{
try
{
parameters[index] = serviceProvider.GetRequiredService(parameterInfo.ParameterType);
}
catch (Exception ex)
{
throw new Exception(string.Format(
"Could not resolve a service of type '{0}' for the parameter '{1}' of method '{2}' on type '{3}'.",
parameterInfo.ParameterType.FullName,
parameterInfo.Name,
MethodInfo.Name,
MethodInfo.DeclaringType.FullName), ex);
}
}
}
MethodInfo.Invoke(instance, parameters);
}
}
}
}

View File

@ -0,0 +1,52 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Reflection;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class ConfigureContainerBuilder
{
public ConfigureContainerBuilder(MethodInfo configureContainerMethod)
{
MethodInfo = configureContainerMethod;
}
public MethodInfo MethodInfo { get; }
public Func<Action<object>, Action<object>> ConfigureContainerFilters { get; set; }
public Action<object> Build(object instance) => container => Invoke(instance, container);
public Type GetContainerType()
{
var parameters = MethodInfo.GetParameters();
if (parameters.Length != 1)
{
// REVIEW: This might be a breaking change
throw new InvalidOperationException($"The {MethodInfo.Name} method must take only one parameter.");
}
return parameters[0].ParameterType;
}
private void Invoke(object instance, object container)
{
ConfigureContainerFilters(StartupConfigureContainer)(container);
void StartupConfigureContainer(object containerBuilder) => InvokeCore(instance, containerBuilder);
}
private void InvokeCore(object instance, object container)
{
if (MethodInfo == null)
{
return;
}
var arguments = new object[1] { container };
MethodInfo.Invoke(instance, arguments);
}
}
}

View File

@ -0,0 +1,56 @@
// 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.Linq;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class ConfigureServicesBuilder
{
public ConfigureServicesBuilder(MethodInfo configureServices)
{
MethodInfo = configureServices;
}
public MethodInfo MethodInfo { get; }
public Func<Func<IServiceCollection, IServiceProvider>, Func<IServiceCollection, IServiceProvider>> StartupServiceFilters { get; set; }
public Func<IServiceCollection, IServiceProvider> Build(object instance) => services => Invoke(instance, services);
private IServiceProvider Invoke(object instance, IServiceCollection services)
{
return StartupServiceFilters(Startup)(services);
IServiceProvider Startup(IServiceCollection serviceCollection) => InvokeCore(instance, serviceCollection);
}
private IServiceProvider InvokeCore(object instance, IServiceCollection services)
{
if (MethodInfo == null)
{
return null;
}
// Only support IServiceCollection parameters
var parameters = MethodInfo.GetParameters();
if (parameters.Length > 1 ||
parameters.Any(p => p.ParameterType != typeof(IServiceCollection)))
{
throw new InvalidOperationException("The ConfigureServices method must either be parameterless or take only one parameter of type IServiceCollection.");
}
var arguments = new object[MethodInfo.GetParameters().Length];
if (parameters.Length > 0)
{
arguments[0] = services;
}
return MethodInfo.Invoke(instance, arguments) as IServiceProvider;
}
}
}

View File

@ -0,0 +1,76 @@
// 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.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class HostedServiceExecutor
{
private readonly IEnumerable<IHostedService> _services;
private readonly ILogger<HostedServiceExecutor> _logger;
public HostedServiceExecutor(ILogger<HostedServiceExecutor> logger, IEnumerable<IHostedService> services)
{
_logger = logger;
_services = services;
}
public async Task StartAsync(CancellationToken token)
{
try
{
await ExecuteAsync(service => service.StartAsync(token));
}
catch (Exception ex)
{
_logger.ApplicationError(LoggerEventIds.HostedServiceStartException, "An error occurred starting the application", ex);
}
}
public async Task StopAsync(CancellationToken token)
{
try
{
await ExecuteAsync(service => service.StopAsync(token));
}
catch (Exception ex)
{
_logger.ApplicationError(LoggerEventIds.HostedServiceStopException, "An error occurred stopping the application", ex);
}
}
private async Task ExecuteAsync(Func<IHostedService, Task> callback)
{
List<Exception> exceptions = null;
foreach (var service in _services)
{
try
{
await callback(service);
}
catch (Exception ex)
{
if (exceptions == null)
{
exceptions = new List<Exception>();
}
exceptions.Add(ex);
}
}
// Throw an aggregate exception if there were any exceptions
if (exceptions != null)
{
throw new AggregateException(exceptions);
}
}
}
}

View File

@ -0,0 +1,67 @@
// 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.Diagnostics;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class HostingApplication : IHttpApplication<HostingApplication.Context>
{
private readonly RequestDelegate _application;
private readonly IHttpContextFactory _httpContextFactory;
private HostingApplicationDiagnostics _diagnostics;
public HostingApplication(
RequestDelegate application,
ILogger logger,
DiagnosticListener diagnosticSource,
IHttpContextFactory httpContextFactory)
{
_application = application;
_diagnostics = new HostingApplicationDiagnostics(logger, diagnosticSource);
_httpContextFactory = httpContextFactory;
}
// Set up the request
public Context CreateContext(IFeatureCollection contextFeatures)
{
var context = new Context();
var httpContext = _httpContextFactory.Create(contextFeatures);
_diagnostics.BeginRequest(httpContext, ref context);
context.HttpContext = httpContext;
return context;
}
// Execute the request
public Task ProcessRequestAsync(Context context)
{
return _application(context.HttpContext);
}
// Clean up the request
public void DisposeContext(Context context, Exception exception)
{
var httpContext = context.HttpContext;
_diagnostics.RequestEnd(httpContext, exception, context);
_httpContextFactory.Dispose(httpContext);
_diagnostics.ContextDisposed(context);
}
public struct Context
{
public HttpContext HttpContext { get; set; }
public IDisposable Scope { get; set; }
public long StartTimestamp { get; set; }
public bool EventLogEnabled { get; set; }
public Activity Activity { get; set; }
}
}
}

View File

@ -0,0 +1,283 @@
// 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.Diagnostics;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Hosting.Internal
{
internal class HostingApplicationDiagnostics
{
private static readonly double TimestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency;
private const string ActivityName = "Microsoft.AspNetCore.Hosting.HttpRequestIn";
private const string ActivityStartKey = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start";
private const string DeprecatedDiagnosticsBeginRequestKey = "Microsoft.AspNetCore.Hosting.BeginRequest";
private const string DeprecatedDiagnosticsEndRequestKey = "Microsoft.AspNetCore.Hosting.EndRequest";
private const string DiagnosticsUnhandledExceptionKey = "Microsoft.AspNetCore.Hosting.UnhandledException";
private const string RequestIdHeaderName = "Request-Id";
private const string CorrelationContextHeaderName = "Correlation-Context";
private readonly DiagnosticListener _diagnosticListener;
private readonly ILogger _logger;
public HostingApplicationDiagnostics(ILogger logger, DiagnosticListener diagnosticListener)
{
_logger = logger;
_diagnosticListener = diagnosticListener;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void BeginRequest(HttpContext httpContext, ref HostingApplication.Context context)
{
long startTimestamp = 0;
if (HostingEventSource.Log.IsEnabled())
{
context.EventLogEnabled = true;
// To keep the hot path short we defer logging in this function to non-inlines
RecordRequestStartEventLog(httpContext);
}
var diagnosticListenerEnabled = _diagnosticListener.IsEnabled();
var loggingEnabled = _logger.IsEnabled(LogLevel.Critical);
// If logging is enabled or the diagnostic listener is enabled, try to get the correlation
// id from the header
StringValues correlationId;
if (diagnosticListenerEnabled || loggingEnabled)
{
httpContext.Request.Headers.TryGetValue(RequestIdHeaderName, out correlationId);
}
if (diagnosticListenerEnabled)
{
if (_diagnosticListener.IsEnabled(ActivityName, httpContext))
{
context.Activity = StartActivity(httpContext, correlationId);
}
if (_diagnosticListener.IsEnabled(DeprecatedDiagnosticsBeginRequestKey))
{
startTimestamp = Stopwatch.GetTimestamp();
RecordBeginRequestDiagnostics(httpContext, startTimestamp);
}
}
// To avoid allocation, return a null scope if the logger is not on at least to some degree.
if (loggingEnabled)
{
// Scope may be relevant for a different level of logging, so we always create it
// see: https://github.com/aspnet/Hosting/pull/944
// Scope can be null if logging is not on.
context.Scope = _logger.RequestScope(httpContext, correlationId);
if (_logger.IsEnabled(LogLevel.Information))
{
if (startTimestamp == 0)
{
startTimestamp = Stopwatch.GetTimestamp();
}
// Non-inline
LogRequestStarting(httpContext);
}
}
context.StartTimestamp = startTimestamp;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RequestEnd(HttpContext httpContext, Exception exception, HostingApplication.Context context)
{
// Local cache items resolved multiple items, in order of use so they are primed in cpu pipeline when used
var startTimestamp = context.StartTimestamp;
long currentTimestamp = 0;
// If startTimestamp was 0, then Information logging wasn't enabled at for this request (and calcuated time will be wildly wrong)
// Is used as proxy to reduce calls to virtual: _logger.IsEnabled(LogLevel.Information)
if (startTimestamp != 0)
{
currentTimestamp = Stopwatch.GetTimestamp();
// Non-inline
LogRequestFinished(httpContext, startTimestamp, currentTimestamp);
}
if (_diagnosticListener.IsEnabled())
{
if (currentTimestamp == 0)
{
currentTimestamp = Stopwatch.GetTimestamp();
}
if (exception == null)
{
// No exception was thrown, request was sucessful
if (_diagnosticListener.IsEnabled(DeprecatedDiagnosticsEndRequestKey))
{
// Diagnostics is enabled for EndRequest, but it may not be for BeginRequest
// so call GetTimestamp if currentTimestamp is zero (from above)
RecordEndRequestDiagnostics(httpContext, currentTimestamp);
}
}
else
{
// Exception was thrown from request
if (_diagnosticListener.IsEnabled(DiagnosticsUnhandledExceptionKey))
{
// Diagnostics is enabled for UnhandledException, but it may not be for BeginRequest
// so call GetTimestamp if currentTimestamp is zero (from above)
RecordUnhandledExceptionDiagnostics(httpContext, currentTimestamp, exception);
}
}
var activity = context.Activity;
// Always stop activity if it was started
if (activity != null)
{
StopActivity(httpContext, activity);
}
}
if (context.EventLogEnabled && exception != null)
{
// Non-inline
HostingEventSource.Log.UnhandledException();
}
// Logging Scope is finshed with
context.Scope?.Dispose();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ContextDisposed(HostingApplication.Context context)
{
if (context.EventLogEnabled)
{
// Non-inline
HostingEventSource.Log.RequestStop();
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void LogRequestStarting(HttpContext httpContext)
{
// IsEnabled is checked in the caller, so if we are here just log
_logger.Log(
logLevel: LogLevel.Information,
eventId: LoggerEventIds.RequestStarting,
state: new HostingRequestStartingLog(httpContext),
exception: null,
formatter: HostingRequestStartingLog.Callback);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void LogRequestFinished(HttpContext httpContext, long startTimestamp, long currentTimestamp)
{
// IsEnabled isn't checked in the caller, startTimestamp > 0 is used as a fast proxy check
// but that may be because diagnostics are enabled, which also uses startTimestamp, so check here
if (_logger.IsEnabled(LogLevel.Information))
{
var elapsed = new TimeSpan((long)(TimestampToTicks * (currentTimestamp - startTimestamp)));
_logger.Log(
logLevel: LogLevel.Information,
eventId: LoggerEventIds.RequestFinished,
state: new HostingRequestFinishedLog(httpContext, elapsed),
exception: null,
formatter: HostingRequestFinishedLog.Callback);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void RecordBeginRequestDiagnostics(HttpContext httpContext, long startTimestamp)
{
_diagnosticListener.Write(
DeprecatedDiagnosticsBeginRequestKey,
new
{
httpContext = httpContext,
timestamp = startTimestamp
});
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void RecordEndRequestDiagnostics(HttpContext httpContext, long currentTimestamp)
{
_diagnosticListener.Write(
DeprecatedDiagnosticsEndRequestKey,
new
{
httpContext = httpContext,
timestamp = currentTimestamp
});
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void RecordUnhandledExceptionDiagnostics(HttpContext httpContext, long currentTimestamp, Exception exception)
{
_diagnosticListener.Write(
DiagnosticsUnhandledExceptionKey,
new
{
httpContext = httpContext,
timestamp = currentTimestamp,
exception = exception
});
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void RecordRequestStartEventLog(HttpContext httpContext)
{
HostingEventSource.Log.RequestStart(httpContext.Request.Method, httpContext.Request.Path);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private Activity StartActivity(HttpContext httpContext, StringValues requestId)
{
var activity = new Activity(ActivityName);
if (!StringValues.IsNullOrEmpty(requestId))
{
activity.SetParentId(requestId);
// We expect baggage to be empty by default
// Only very advanced users will be using it in near future, we encourage them to keep baggage small (few items)
string[] baggage = httpContext.Request.Headers.GetCommaSeparatedValues(CorrelationContextHeaderName);
if (baggage != StringValues.Empty)
{
foreach (var item in baggage)
{
if (NameValueHeaderValue.TryParse(item, out var baggageItem))
{
activity.AddBaggage(baggageItem.Name.ToString(), baggageItem.Value.ToString());
}
}
}
}
if (_diagnosticListener.IsEnabled(ActivityStartKey))
{
_diagnosticListener.StartActivity(activity, new { HttpContext = httpContext });
}
else
{
activity.Start();
}
return activity;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void StopActivity(HttpContext httpContext, Activity activity)
{
_diagnosticListener.StopActivity(activity, new { HttpContext = httpContext });
}
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Extensions.FileProviders;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class HostingEnvironment : IHostingEnvironment, Extensions.Hosting.IHostingEnvironment
{
public string EnvironmentName { get; set; } = Hosting.EnvironmentName.Production;
public string ApplicationName { get; set; }
public string WebRootPath { get; set; }
public IFileProvider WebRootFileProvider { get; set; }
public string ContentRootPath { get; set; }
public IFileProvider ContentRootFileProvider { get; set; }
}
}

View File

@ -0,0 +1,65 @@
// 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.IO;
using Microsoft.Extensions.FileProviders;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public static class HostingEnvironmentExtensions
{
public static void Initialize(this IHostingEnvironment hostingEnvironment, string contentRootPath, WebHostOptions options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
if (string.IsNullOrEmpty(contentRootPath))
{
throw new ArgumentException("A valid non-empty content root must be provided.", nameof(contentRootPath));
}
if (!Directory.Exists(contentRootPath))
{
throw new ArgumentException($"The content root '{contentRootPath}' does not exist.", nameof(contentRootPath));
}
hostingEnvironment.ApplicationName = options.ApplicationName;
hostingEnvironment.ContentRootPath = contentRootPath;
hostingEnvironment.ContentRootFileProvider = new PhysicalFileProvider(hostingEnvironment.ContentRootPath);
var webRoot = options.WebRoot;
if (webRoot == null)
{
// Default to /wwwroot if it exists.
var wwwroot = Path.Combine(hostingEnvironment.ContentRootPath, "wwwroot");
if (Directory.Exists(wwwroot))
{
hostingEnvironment.WebRootPath = wwwroot;
}
}
else
{
hostingEnvironment.WebRootPath = Path.Combine(hostingEnvironment.ContentRootPath, webRoot);
}
if (!string.IsNullOrEmpty(hostingEnvironment.WebRootPath))
{
hostingEnvironment.WebRootPath = Path.GetFullPath(hostingEnvironment.WebRootPath);
if (!Directory.Exists(hostingEnvironment.WebRootPath))
{
Directory.CreateDirectory(hostingEnvironment.WebRootPath);
}
hostingEnvironment.WebRootFileProvider = new PhysicalFileProvider(hostingEnvironment.WebRootPath);
}
else
{
hostingEnvironment.WebRootFileProvider = new NullFileProvider();
}
hostingEnvironment.EnvironmentName =
options.Environment ??
hostingEnvironment.EnvironmentName;
}
}
}

View File

@ -0,0 +1,55 @@
// 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.Diagnostics.Tracing;
using System.Runtime.CompilerServices;
namespace Microsoft.AspNetCore.Hosting.Internal
{
[EventSource(Name = "Microsoft-AspNetCore-Hosting")]
public sealed class HostingEventSource : EventSource
{
public static readonly HostingEventSource Log = new HostingEventSource();
private HostingEventSource() { }
// NOTE
// - The 'Start' and 'Stop' suffixes on the following event names have special meaning in EventSource. They
// enable creating 'activities'.
// For more information, take a look at the following blog post:
// https://blogs.msdn.microsoft.com/vancem/2015/09/14/exploring-eventsource-activity-correlation-and-causation-features/
// - A stop event's event id must be next one after its start event.
[Event(1, Level = EventLevel.Informational)]
public void HostStart()
{
WriteEvent(1);
}
[Event(2, Level = EventLevel.Informational)]
public void HostStop()
{
WriteEvent(2);
}
[Event(3, Level = EventLevel.Informational)]
public void RequestStart(string method, string path)
{
WriteEvent(3, method, path);
}
[MethodImpl(MethodImplOptions.NoInlining)]
[Event(4, Level = EventLevel.Informational)]
public void RequestStop()
{
WriteEvent(4);
}
[MethodImpl(MethodImplOptions.NoInlining)]
[Event(5, Level = EventLevel.Error)]
public void UnhandledException()
{
WriteEvent(5);
}
}
}

View File

@ -0,0 +1,168 @@
// 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;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Hosting.Internal
{
internal static class HostingLoggerExtensions
{
public static IDisposable RequestScope(this ILogger logger, HttpContext httpContext, string correlationId)
{
return logger.BeginScope(new HostingLogScope(httpContext, correlationId));
}
public static void ApplicationError(this ILogger logger, Exception exception)
{
logger.ApplicationError(
eventId: LoggerEventIds.ApplicationStartupException,
message: "Application startup exception",
exception: exception);
}
public static void HostingStartupAssemblyError(this ILogger logger, Exception exception)
{
logger.ApplicationError(
eventId: LoggerEventIds.HostingStartupAssemblyException,
message: "Hosting startup assembly exception",
exception: exception);
}
public static void ApplicationError(this ILogger logger, EventId eventId, string message, Exception exception)
{
var reflectionTypeLoadException = exception as ReflectionTypeLoadException;
if (reflectionTypeLoadException != null)
{
foreach (var ex in reflectionTypeLoadException.LoaderExceptions)
{
message = message + Environment.NewLine + ex.Message;
}
}
logger.LogCritical(
eventId: eventId,
message: message,
exception: exception);
}
public static void Starting(this ILogger logger)
{
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug(
eventId: LoggerEventIds.Starting,
message: "Hosting starting");
}
}
public static void Started(this ILogger logger)
{
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug(
eventId: LoggerEventIds.Started,
message: "Hosting started");
}
}
public static void Shutdown(this ILogger logger)
{
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug(
eventId: LoggerEventIds.Shutdown,
message: "Hosting shutdown");
}
}
public static void ServerShutdownException(this ILogger logger, Exception ex)
{
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug(
eventId: LoggerEventIds.ServerShutdownException,
exception: ex,
message: "Server shutdown exception");
}
}
private class HostingLogScope : IReadOnlyList<KeyValuePair<string, object>>
{
private readonly string _path;
private readonly string _traceIdentifier;
private readonly string _correlationId;
private string _cachedToString;
public int Count
{
get
{
return 3;
}
}
public KeyValuePair<string, object> this[int index]
{
get
{
if (index == 0)
{
return new KeyValuePair<string, object>("RequestId", _traceIdentifier);
}
else if (index == 1)
{
return new KeyValuePair<string, object>("RequestPath", _path);
}
else if (index == 2)
{
return new KeyValuePair<string, object>("CorrelationId", _correlationId);
}
throw new ArgumentOutOfRangeException(nameof(index));
}
}
public HostingLogScope(HttpContext httpContext, string correlationId)
{
_traceIdentifier = httpContext.TraceIdentifier;
_path = httpContext.Request.Path.ToString();
_correlationId = correlationId;
}
public override string ToString()
{
if (_cachedToString == null)
{
_cachedToString = string.Format(
CultureInfo.InvariantCulture,
"RequestId:{0} RequestPath:{1}",
_traceIdentifier,
_path);
}
return _cachedToString;
}
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
for (int i = 0; i < Count; ++i)
{
yield return this[i];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
}

View File

@ -0,0 +1,75 @@
// 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;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Hosting.Internal
{
internal class HostingRequestFinishedLog : IReadOnlyList<KeyValuePair<string, object>>
{
internal static readonly Func<object, Exception, string> Callback = (state, exception) => ((HostingRequestFinishedLog)state).ToString();
private readonly HttpContext _httpContext;
private readonly TimeSpan _elapsed;
private string _cachedToString;
public int Count => 3;
public KeyValuePair<string, object> this[int index]
{
get
{
switch (index)
{
case 0:
return new KeyValuePair<string, object>("ElapsedMilliseconds", _elapsed.TotalMilliseconds);
case 1:
return new KeyValuePair<string, object>("StatusCode", _httpContext.Response.StatusCode);
case 2:
return new KeyValuePair<string, object>("ContentType", _httpContext.Response.ContentType);
default:
throw new IndexOutOfRangeException(nameof(index));
}
}
}
public HostingRequestFinishedLog(HttpContext httpContext, TimeSpan elapsed)
{
_httpContext = httpContext;
_elapsed = elapsed;
}
public override string ToString()
{
if (_cachedToString == null)
{
_cachedToString = string.Format(
CultureInfo.InvariantCulture,
"Request finished in {0}ms {1} {2}",
_elapsed.TotalMilliseconds,
_httpContext.Response.StatusCode,
_httpContext.Response.ContentType);
}
return _cachedToString;
}
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return this[i];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

View File

@ -0,0 +1,91 @@
// 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;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Hosting.Internal
{
internal class HostingRequestStartingLog : IReadOnlyList<KeyValuePair<string, object>>
{
internal static readonly Func<object, Exception, string> Callback = (state, exception) => ((HostingRequestStartingLog)state).ToString();
private readonly HttpRequest _request;
private string _cachedToString;
public int Count => 9;
public KeyValuePair<string, object> this[int index]
{
get
{
switch (index)
{
case 0:
return new KeyValuePair<string, object>("Protocol", _request.Protocol);
case 1:
return new KeyValuePair<string, object>("Method", _request.Method);
case 2:
return new KeyValuePair<string, object>("ContentType", _request.ContentType);
case 3:
return new KeyValuePair<string, object>("ContentLength", _request.ContentLength);
case 4:
return new KeyValuePair<string, object>("Scheme", _request.Scheme.ToString());
case 5:
return new KeyValuePair<string, object>("Host", _request.Host.ToString());
case 6:
return new KeyValuePair<string, object>("PathBase", _request.PathBase.ToString());
case 7:
return new KeyValuePair<string, object>("Path", _request.Path.ToString());
case 8:
return new KeyValuePair<string, object>("QueryString", _request.QueryString.ToString());
default:
throw new IndexOutOfRangeException(nameof(index));
}
}
}
public HostingRequestStartingLog(HttpContext httpContext)
{
_request = httpContext.Request;
}
public override string ToString()
{
if (_cachedToString == null)
{
_cachedToString = string.Format(
CultureInfo.InvariantCulture,
"Request starting {0} {1} {2}://{3}{4}{5}{6} {7} {8}",
_request.Protocol,
_request.Method,
_request.Scheme,
_request.Host.Value,
_request.PathBase.Value,
_request.Path.Value,
_request.QueryString.Value,
_request.ContentType,
_request.ContentLength);
}
return _cachedToString;
}
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return this[i];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

View File

@ -0,0 +1,21 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Hosting.Internal
{
internal static class LoggerEventIds
{
public const int RequestStarting = 1;
public const int RequestFinished = 2;
public const int Starting = 3;
public const int Started = 4;
public const int Shutdown = 5;
public const int ApplicationStartupException = 6;
public const int ApplicationStoppingException = 7;
public const int ApplicationStoppedException = 8;
public const int HostedServiceStartException = 9;
public const int HostedServiceStopException = 10;
public const int HostingStartupAssemblyException = 11;
public const int ServerShutdownException = 12;
}
}

View File

@ -0,0 +1,50 @@
// 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.Diagnostics;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class RequestServicesContainerMiddleware
{
private readonly RequestDelegate _next;
private readonly IServiceScopeFactory _scopeFactory;
public RequestServicesContainerMiddleware(RequestDelegate next, IServiceScopeFactory scopeFactory)
{
if (next == null)
{
throw new ArgumentNullException(nameof(next));
}
if (scopeFactory == null)
{
throw new ArgumentNullException(nameof(scopeFactory));
}
_next = next;
_scopeFactory = scopeFactory;
}
public Task Invoke(HttpContext httpContext)
{
Debug.Assert(httpContext != null);
var features = httpContext.Features;
var servicesFeature = features.Get<IServiceProvidersFeature>();
// All done if RequestServices is set
if (servicesFeature?.RequestServices != null)
{
return _next.Invoke(httpContext);
}
features.Set<IServiceProvidersFeature>(new RequestServicesFeature(httpContext, _scopeFactory));
return _next.Invoke(httpContext);
}
}
}

View File

@ -0,0 +1,55 @@
// 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.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class RequestServicesFeature : IServiceProvidersFeature, IDisposable
{
private readonly IServiceScopeFactory _scopeFactory;
private IServiceProvider _requestServices;
private IServiceScope _scope;
private bool _requestServicesSet;
private HttpContext _context;
public RequestServicesFeature(HttpContext context, IServiceScopeFactory scopeFactory)
{
Debug.Assert(scopeFactory != null);
_context = context;
_scopeFactory = scopeFactory;
}
public IServiceProvider RequestServices
{
get
{
if (!_requestServicesSet)
{
_context.Response.RegisterForDispose(this);
_scope = _scopeFactory.CreateScope();
_requestServices = _scope.ServiceProvider;
_requestServicesSet = true;
}
return _requestServices;
}
set
{
_requestServices = value;
_requestServicesSet = true;
}
}
public void Dispose()
{
_scope?.Dispose();
_scope = null;
_requestServices = null;
}
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting.Internal
{
internal static class ServiceCollectionExtensions
{
public static IServiceCollection Clone(this IServiceCollection serviceCollection)
{
IServiceCollection clone = new ServiceCollection();
foreach (var service in serviceCollection)
{
clone.Add(service);
}
return clone;
}
}
}

View File

@ -0,0 +1,336 @@
// 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.Globalization;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class StartupLoader
{
// Creates an <see cref="StartupMethods"/> instance with the actions to run for configuring the application services and the
// request pipeline of the application.
// When using convention based startup, the process for initializing the services is as follows:
// The host looks for a method with the signature <see cref="IServiceProvider"/> ConfigureServices(<see cref="IServiceCollection"/> services).
// If it can't find one, it looks for a method with the signature <see cref="void"/> ConfigureServices(<see cref="IServiceCollection"/> services).
// When the configure services method is void returning, the host builds a services configuration function that runs all the <see cref="IStartupConfigureServicesFilter"/>
// instances registered on the host, along with the ConfigureServices method following a decorator pattern.
// Additionally to the ConfigureServices method, the Startup class can define a <see cref="void"/> ConfigureContainer&lt;TContainerBuilder&gt;(TContainerBuilder builder)
// method that further configures services into the container. If the ConfigureContainer method is defined, the services configuration function
// creates a TContainerBuilder <see cref="IServiceProviderFactory{TContainerBuilder}"/> and runs all the <see cref="IStartupConfigureContainerFilter{TContainerBuilder}"/>
// instances registered on the host, along with the ConfigureContainer method following a decorator pattern.
// For example:
// StartupFilter1
// StartupFilter2
// ConfigureServices
// StartupFilter2
// StartupFilter1
// ConfigureContainerFilter1
// ConfigureContainerFilter2
// ConfigureContainer
// ConfigureContainerFilter2
// ConfigureContainerFilter1
//
// If the Startup class ConfigureServices returns an <see cref="IServiceProvider"/> and there is at least an <see cref="IStartupConfigureServicesFilter"/> registered we
// throw as the filters can't be applied.
public static StartupMethods LoadMethods(IServiceProvider hostingServiceProvider, Type startupType, string environmentName)
{
var configureMethod = FindConfigureDelegate(startupType, environmentName);
var servicesMethod = FindConfigureServicesDelegate(startupType, environmentName);
var configureContainerMethod = FindConfigureContainerDelegate(startupType, environmentName);
object instance = null;
if (!configureMethod.MethodInfo.IsStatic || (servicesMethod != null && !servicesMethod.MethodInfo.IsStatic))
{
instance = ActivatorUtilities.GetServiceOrCreateInstance(hostingServiceProvider, startupType);
}
// The type of the TContainerBuilder. If there is no ConfigureContainer method we can just use object as it's not
// going to be used for anything.
var type = configureContainerMethod.MethodInfo != null ? configureContainerMethod.GetContainerType() : typeof(object);
var builder = (ConfigureServicesDelegateBuilder) Activator.CreateInstance(
typeof(ConfigureServicesDelegateBuilder<>).MakeGenericType(type),
hostingServiceProvider,
servicesMethod,
configureContainerMethod,
instance);
return new StartupMethods(instance, configureMethod.Build(instance), builder.Build());
}
private abstract class ConfigureServicesDelegateBuilder
{
public abstract Func<IServiceCollection, IServiceProvider> Build();
}
private class ConfigureServicesDelegateBuilder<TContainerBuilder> : ConfigureServicesDelegateBuilder
{
public ConfigureServicesDelegateBuilder(
IServiceProvider hostingServiceProvider,
ConfigureServicesBuilder configureServicesBuilder,
ConfigureContainerBuilder configureContainerBuilder,
object instance)
{
HostingServiceProvider = hostingServiceProvider;
ConfigureServicesBuilder = configureServicesBuilder;
ConfigureContainerBuilder = configureContainerBuilder;
Instance = instance;
}
public IServiceProvider HostingServiceProvider { get; }
public ConfigureServicesBuilder ConfigureServicesBuilder { get; }
public ConfigureContainerBuilder ConfigureContainerBuilder { get; }
public object Instance { get; }
public override Func<IServiceCollection, IServiceProvider> Build()
{
ConfigureServicesBuilder.StartupServiceFilters = BuildStartupServicesFilterPipeline;
var configureServicesCallback = ConfigureServicesBuilder.Build(Instance);
ConfigureContainerBuilder.ConfigureContainerFilters = ConfigureContainerPipeline;
var configureContainerCallback = ConfigureContainerBuilder.Build(Instance);
return ConfigureServices(configureServicesCallback, configureContainerCallback);
Action<object> ConfigureContainerPipeline(Action<object> action)
{
return Target;
// The ConfigureContainer pipeline needs an Action<TContainerBuilder> as source, so we just adapt the
// signature with this function.
void Source(TContainerBuilder containerBuilder) =>
action(containerBuilder);
// The ConfigureContainerBuilder.ConfigureContainerFilters expects an Action<object> as value, but our pipeline
// produces an Action<TContainerBuilder> given a source, so we wrap it on an Action<object> that internally casts
// the object containerBuilder to TContainerBuilder to match the expected signature of our ConfigureContainer pipeline.
void Target(object containerBuilder) =>
BuildStartupConfigureContainerFiltersPipeline(Source)((TContainerBuilder)containerBuilder);
}
}
Func<IServiceCollection, IServiceProvider> ConfigureServices(
Func<IServiceCollection, IServiceProvider> configureServicesCallback,
Action<object> configureContainerCallback)
{
return ConfigureServicesWithContainerConfiguration;
IServiceProvider ConfigureServicesWithContainerConfiguration(IServiceCollection services)
{
// Call ConfigureServices, if that returned an IServiceProvider, we're done
IServiceProvider applicationServiceProvider = configureServicesCallback.Invoke(services);
if (applicationServiceProvider != null)
{
return applicationServiceProvider;
}
// If there's a ConfigureContainer method
if (ConfigureContainerBuilder.MethodInfo != null)
{
var serviceProviderFactory = HostingServiceProvider.GetRequiredService<IServiceProviderFactory<TContainerBuilder>>();
var builder = serviceProviderFactory.CreateBuilder(services);
configureContainerCallback(builder);
applicationServiceProvider = serviceProviderFactory.CreateServiceProvider(builder);
}
else
{
// Get the default factory
var serviceProviderFactory = HostingServiceProvider.GetRequiredService<IServiceProviderFactory<IServiceCollection>>();
var builder = serviceProviderFactory.CreateBuilder(services);
applicationServiceProvider = serviceProviderFactory.CreateServiceProvider(builder);
}
return applicationServiceProvider ?? services.BuildServiceProvider();
}
}
private Func<IServiceCollection, IServiceProvider> BuildStartupServicesFilterPipeline(Func<IServiceCollection, IServiceProvider> startup)
{
return RunPipeline;
IServiceProvider RunPipeline(IServiceCollection services)
{
var filters = HostingServiceProvider.GetRequiredService<IEnumerable<IStartupConfigureServicesFilter>>().Reverse().ToArray();
// If there are no filters just run startup (makes IServiceProvider ConfigureServices(IServiceCollection services) work.
if (filters.Length == 0)
{
return startup(services);
}
Action<IServiceCollection> pipeline = InvokeStartup;
for (int i = 0; i < filters.Length; i++)
{
pipeline = filters[i].ConfigureServices(pipeline);
}
pipeline(services);
// We return null so that the host here builds the container (same result as void ConfigureServices(IServiceCollection services);
return null;
void InvokeStartup(IServiceCollection serviceCollection)
{
var result = startup(serviceCollection);
if (filters.Length > 0 && result != null)
{
// public IServiceProvider ConfigureServices(IServiceCollection serviceCollection) is not compatible with IStartupServicesFilter;
var message = $"A ConfigureServices method that returns an {nameof(IServiceProvider)} is " +
$"not compatible with the use of one or more {nameof(IStartupConfigureServicesFilter)}. " +
$"Use a void returning ConfigureServices method instead or a ConfigureContainer method.";
throw new InvalidOperationException(message);
};
}
}
}
private Action<TContainerBuilder> BuildStartupConfigureContainerFiltersPipeline(Action<TContainerBuilder> configureContainer)
{
return RunPipeline;
void RunPipeline(TContainerBuilder containerBuilder)
{
var filters = HostingServiceProvider
.GetRequiredService<IEnumerable<IStartupConfigureContainerFilter<TContainerBuilder>>>()
.Reverse()
.ToArray();
Action<TContainerBuilder> pipeline = InvokeConfigureContainer;
for (int i = 0; i < filters.Length; i++)
{
pipeline = filters[i].ConfigureContainer(pipeline);
}
pipeline(containerBuilder);
void InvokeConfigureContainer(TContainerBuilder builder) => configureContainer(builder);
}
}
}
public static Type FindStartupType(string startupAssemblyName, string environmentName)
{
if (string.IsNullOrEmpty(startupAssemblyName))
{
throw new ArgumentException(
string.Format("A startup method, startup type or startup assembly is required. If specifying an assembly, '{0}' cannot be null or empty.",
nameof(startupAssemblyName)),
nameof(startupAssemblyName));
}
var assembly = Assembly.Load(new AssemblyName(startupAssemblyName));
if (assembly == null)
{
throw new InvalidOperationException(String.Format("The assembly '{0}' failed to load.", startupAssemblyName));
}
var startupNameWithEnv = "Startup" + environmentName;
var startupNameWithoutEnv = "Startup";
// Check the most likely places first
var type =
assembly.GetType(startupNameWithEnv) ??
assembly.GetType(startupAssemblyName + "." + startupNameWithEnv) ??
assembly.GetType(startupNameWithoutEnv) ??
assembly.GetType(startupAssemblyName + "." + startupNameWithoutEnv);
if (type == null)
{
// Full scan
var definedTypes = assembly.DefinedTypes.ToList();
var startupType1 = definedTypes.Where(info => info.Name.Equals(startupNameWithEnv, StringComparison.OrdinalIgnoreCase));
var startupType2 = definedTypes.Where(info => info.Name.Equals(startupNameWithoutEnv, StringComparison.OrdinalIgnoreCase));
var typeInfo = startupType1.Concat(startupType2).FirstOrDefault();
if (typeInfo != null)
{
type = typeInfo.AsType();
}
}
if (type == null)
{
throw new InvalidOperationException(String.Format("A type named '{0}' or '{1}' could not be found in assembly '{2}'.",
startupNameWithEnv,
startupNameWithoutEnv,
startupAssemblyName));
}
return type;
}
private 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)
{
var configureMethod = FindMethod(startupType, "Configure{0}Container", environmentName, typeof(void), required: false);
return new ConfigureContainerBuilder(configureMethod);
}
private 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);
return new ConfigureServicesBuilder(servicesMethod);
}
private static MethodInfo FindMethod(Type startupType, string methodName, string environmentName, Type returnType = null, bool required = true)
{
var methodNameWithEnv = string.Format(CultureInfo.InvariantCulture, methodName, environmentName);
var methodNameWithNoEnv = string.Format(CultureInfo.InvariantCulture, methodName, "");
var methods = startupType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
var selectedMethods = methods.Where(method => method.Name.Equals(methodNameWithEnv, StringComparison.OrdinalIgnoreCase)).ToList();
if (selectedMethods.Count > 1)
{
throw new InvalidOperationException(string.Format("Having multiple overloads of method '{0}' is not supported.", methodNameWithEnv));
}
if (selectedMethods.Count == 0)
{
selectedMethods = methods.Where(method => method.Name.Equals(methodNameWithNoEnv, StringComparison.OrdinalIgnoreCase)).ToList();
if (selectedMethods.Count > 1)
{
throw new InvalidOperationException(string.Format("Having multiple overloads of method '{0}' is not supported.", methodNameWithNoEnv));
}
}
var methodInfo = selectedMethods.FirstOrDefault();
if (methodInfo == null)
{
if (required)
{
throw new InvalidOperationException(string.Format("A public method named '{0}' or '{1}' could not be found in the '{2}' type.",
methodNameWithEnv,
methodNameWithNoEnv,
startupType.FullName));
}
return null;
}
if (returnType != null && methodInfo.ReturnType != returnType)
{
if (required)
{
throw new InvalidOperationException(string.Format("The '{0}' method in the type '{1}' must have a return type of '{2}'.",
methodInfo.Name,
startupType.FullName,
returnType.Name));
}
return null;
}
return methodInfo;
}
}
}

View File

@ -0,0 +1,28 @@
// 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.Diagnostics;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class StartupMethods
{
public StartupMethods(object instance, Action<IApplicationBuilder> configure, Func<IServiceCollection, IServiceProvider> configureServices)
{
Debug.Assert(configure != null);
Debug.Assert(configureServices != null);
StartupInstance = instance;
ConfigureDelegate = configure;
ConfigureServicesDelegate = configureServices;
}
public object StartupInstance { get; }
public Func<IServiceCollection, IServiceProvider> ConfigureServicesDelegate { get; }
public Action<IApplicationBuilder> ConfigureDelegate { get; }
}
}

View File

@ -0,0 +1,362 @@
// 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 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.AspNetCore.Http.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.StackTrace.Sources;
namespace Microsoft.AspNetCore.Hosting.Internal
{
internal class WebHost : IWebHost
{
private static readonly string DeprecatedServerUrlsKey = "server.urls";
private readonly IServiceCollection _applicationServiceCollection;
private IStartup _startup;
private ApplicationLifetime _applicationLifetime;
private HostedServiceExecutor _hostedServiceExecutor;
private readonly IServiceProvider _hostingServiceProvider;
private readonly WebHostOptions _options;
private readonly IConfiguration _config;
private readonly AggregateException _hostingStartupErrors;
private IServiceProvider _applicationServices;
private ExceptionDispatchInfo _applicationServicesException;
private ILogger<WebHost> _logger;
private bool _stopped;
// Used for testing only
internal WebHostOptions Options => _options;
private IServer Server { get; set; }
public WebHost(
IServiceCollection appServices,
IServiceProvider hostingServiceProvider,
WebHostOptions options,
IConfiguration config,
AggregateException hostingStartupErrors)
{
if (appServices == null)
{
throw new ArgumentNullException(nameof(appServices));
}
if (hostingServiceProvider == null)
{
throw new ArgumentNullException(nameof(hostingServiceProvider));
}
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
_config = config;
_hostingStartupErrors = hostingStartupErrors;
_options = options;
_applicationServiceCollection = appServices;
_hostingServiceProvider = hostingServiceProvider;
_applicationServiceCollection.AddSingleton<IApplicationLifetime, ApplicationLifetime>();
// There's no way to to register multiple service types per definition. See https://github.com/aspnet/DependencyInjection/issues/360
_applicationServiceCollection.AddSingleton(sp =>
{
return sp.GetRequiredService<IApplicationLifetime>() as Extensions.Hosting.IApplicationLifetime;
});
_applicationServiceCollection.AddSingleton<HostedServiceExecutor>();
}
public IServiceProvider Services
{
get
{
return _applicationServices;
}
}
public IFeatureCollection ServerFeatures
{
get
{
EnsureServer();
return Server?.Features;
}
}
// Called immediately after the constructor so the properties can rely on it.
public void Initialize()
{
try
{
EnsureApplicationServices();
}
catch (Exception ex)
{
// EnsureApplicationServices may have failed due to a missing or throwing Startup class.
if (_applicationServices == null)
{
_applicationServices = _applicationServiceCollection.BuildServiceProvider();
}
if (!_options.CaptureStartupErrors)
{
throw;
}
_applicationServicesException = ExceptionDispatchInfo.Capture(ex);
}
}
public void Start()
{
StartAsync().GetAwaiter().GetResult();
}
public virtual async Task StartAsync(CancellationToken cancellationToken = default)
{
HostingEventSource.Log.HostStart();
_logger = _applicationServices.GetRequiredService<ILogger<WebHost>>();
_logger.Starting();
var application = BuildApplication();
_applicationLifetime = _applicationServices.GetRequiredService<IApplicationLifetime>() as ApplicationLifetime;
_hostedServiceExecutor = _applicationServices.GetRequiredService<HostedServiceExecutor>();
var diagnosticSource = _applicationServices.GetRequiredService<DiagnosticListener>();
var httpContextFactory = _applicationServices.GetRequiredService<IHttpContextFactory>();
var hostingApp = new HostingApplication(application, _logger, diagnosticSource, httpContextFactory);
await Server.StartAsync(hostingApp, cancellationToken).ConfigureAwait(false);
// Fire IApplicationLifetime.Started
_applicationLifetime?.NotifyStarted();
// Fire IHostedService.Start
await _hostedServiceExecutor.StartAsync(cancellationToken).ConfigureAwait(false);
_logger.Started();
// Log the fact that we did load hosting startup assemblies.
if (_logger.IsEnabled(LogLevel.Debug))
{
foreach (var assembly in _options.GetFinalHostingStartupAssemblies())
{
_logger.LogDebug("Loaded hosting startup assembly {assemblyName}", assembly);
}
}
if (_hostingStartupErrors != null)
{
foreach (var exception in _hostingStartupErrors.InnerExceptions)
{
_logger.HostingStartupAssemblyError(exception);
}
}
}
private void EnsureApplicationServices()
{
if (_applicationServices == null)
{
EnsureStartup();
_applicationServices = _startup.ConfigureServices(_applicationServiceCollection);
}
}
private void EnsureStartup()
{
if (_startup != null)
{
return;
}
_startup = _hostingServiceProvider.GetService<IStartup>();
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.");
}
}
private RequestDelegate BuildApplication()
{
try
{
_applicationServicesException?.Throw();
EnsureServer();
var builderFactory = _applicationServices.GetRequiredService<IApplicationBuilderFactory>();
var builder = builderFactory.CreateBuilder(Server.Features);
builder.ApplicationServices = _applicationServices;
var startupFilters = _applicationServices.GetService<IEnumerable<IStartupFilter>>();
Action<IApplicationBuilder> configure = _startup.Configure;
foreach (var filter in startupFilters.Reverse())
{
configure = filter.Configure(configure);
}
configure(builder);
return builder.Build();
}
catch (Exception ex)
{
if (!_options.SuppressStatusMessages)
{
// Write errors to standard out so they can be retrieved when not in development mode.
Console.WriteLine("Application startup exception: " + ex.ToString());
}
var logger = _applicationServices.GetRequiredService<ILogger<WebHost>>();
logger.ApplicationError(ex);
if (!_options.CaptureStartupErrors)
{
throw;
}
EnsureServer();
// Generate an HTML error page.
var hostingEnv = _applicationServices.GetRequiredService<IHostingEnvironment>();
var showDetailedErrors = hostingEnv.IsDevelopment() || _options.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<AssemblyInformationalVersionAttribute>()
.InformationalVersion;
model.ClrVersion = clrVersion;
model.OperatingSystemDescription = RuntimeInformation.OSDescription;
if (showDetailedErrors)
{
var exceptionDetailProvider = new ExceptionDetailsProvider(
hostingEnv.ContentRootFileProvider,
sourceCodeLineCount: 6);
model.ErrorDetails = exceptionDetailProvider.GetDetails(ex);
}
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);
};
}
}
private void EnsureServer()
{
if (Server == null)
{
Server = _applicationServices.GetRequiredService<IServer>();
var serverAddressesFeature = Server.Features?.Get<IServerAddressesFeature>();
var addresses = serverAddressesFeature?.Addresses;
if (addresses != null && !addresses.IsReadOnly && addresses.Count == 0)
{
var urls = _config[WebHostDefaults.ServerUrlsKey] ?? _config[DeprecatedServerUrlsKey];
if (!string.IsNullOrEmpty(urls))
{
serverAddressesFeature.PreferHostingUrls = WebHostUtilities.ParseBool(_config, WebHostDefaults.PreferHostingUrlsKey);
foreach (var value in urls.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
{
addresses.Add(value);
}
}
}
}
}
public async Task StopAsync(CancellationToken cancellationToken = default)
{
if (_stopped)
{
return;
}
_stopped = true;
_logger?.Shutdown();
var timeoutToken = new CancellationTokenSource(Options.ShutdownTimeout).Token;
if (!cancellationToken.CanBeCanceled)
{
cancellationToken = timeoutToken;
}
else
{
cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutToken).Token;
}
// Fire IApplicationLifetime.Stopping
_applicationLifetime?.StopApplication();
if (Server != null)
{
await Server.StopAsync(cancellationToken).ConfigureAwait(false);
}
// Fire the IHostedService.Stop
if (_hostedServiceExecutor != null)
{
await _hostedServiceExecutor.StopAsync(cancellationToken).ConfigureAwait(false);
}
// Fire IApplicationLifetime.Stopped
_applicationLifetime?.NotifyStopped();
HostingEventSource.Log.HostStop();
}
public void Dispose()
{
if (!_stopped)
{
try
{
StopAsync().GetAwaiter().GetResult();
}
catch (Exception ex)
{
_logger?.ServerShutdownException(ex);
}
}
(_applicationServices as IDisposable)?.Dispose();
(_hostingServiceProvider as IDisposable)?.Dispose();
}
}
}

View File

@ -0,0 +1,96 @@
// 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.Globalization;
using System.Linq;
using Microsoft.Extensions.Configuration;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class WebHostOptions
{
public WebHostOptions() { }
public WebHostOptions(IConfiguration configuration)
: this(configuration, string.Empty) { }
public WebHostOptions(IConfiguration configuration, string applicationNameFallback)
{
if (configuration == null)
{
throw new ArgumentNullException(nameof(configuration));
}
ApplicationName = configuration[WebHostDefaults.ApplicationKey] ?? applicationNameFallback;
StartupAssembly = configuration[WebHostDefaults.StartupAssemblyKey];
DetailedErrors = WebHostUtilities.ParseBool(configuration, WebHostDefaults.DetailedErrorsKey);
CaptureStartupErrors = WebHostUtilities.ParseBool(configuration, WebHostDefaults.CaptureStartupErrorsKey);
Environment = configuration[WebHostDefaults.EnvironmentKey];
WebRoot = configuration[WebHostDefaults.WebRootKey];
ContentRootPath = configuration[WebHostDefaults.ContentRootKey];
PreventHostingStartup = WebHostUtilities.ParseBool(configuration, WebHostDefaults.PreventHostingStartupKey);
SuppressStatusMessages = WebHostUtilities.ParseBool(configuration, WebHostDefaults.SuppressStatusMessagesKey);
// Search the primary assembly and configured assemblies.
HostingStartupAssemblies = Split($"{ApplicationName};{configuration[WebHostDefaults.HostingStartupAssembliesKey]}");
HostingStartupExcludeAssemblies = Split(configuration[WebHostDefaults.HostingStartupExcludeAssembliesKey]);
var timeout = configuration[WebHostDefaults.ShutdownTimeoutKey];
if (!string.IsNullOrEmpty(timeout)
&& int.TryParse(timeout, NumberStyles.None, CultureInfo.InvariantCulture, out var seconds))
{
ShutdownTimeout = TimeSpan.FromSeconds(seconds);
}
}
public string ApplicationName { get; set; }
public bool PreventHostingStartup { get; set; }
public bool SuppressStatusMessages { get; set; }
public IReadOnlyList<string> HostingStartupAssemblies { get; set; }
public IReadOnlyList<string> HostingStartupExcludeAssemblies { get; set; }
public bool DetailedErrors { get; set; }
public bool CaptureStartupErrors { get; set; }
public string Environment { get; set; }
public string StartupAssembly { get; set; }
public string WebRoot { get; set; }
public string ContentRootPath { get; set; }
public TimeSpan ShutdownTimeout { get; set; } = TimeSpan.FromSeconds(5);
public IEnumerable<string> GetFinalHostingStartupAssemblies()
{
return HostingStartupAssemblies.Except(HostingStartupExcludeAssemblies, StringComparer.OrdinalIgnoreCase);
}
private IReadOnlyList<string> Split(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return Array.Empty<string>();
}
var list = new List<string>();
foreach (var part in value.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
{
var trimmedPart = part;
if (!string.IsNullOrEmpty(trimmedPart))
{
list.Add(trimmedPart);
}
}
return list;
}
}
}

View File

@ -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.Extensions.Configuration;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class WebHostUtilities
{
public static bool ParseBool(IConfiguration configuration, string key)
{
return string.Equals("true", configuration[key], StringComparison.OrdinalIgnoreCase)
|| string.Equals("1", configuration[key], StringComparison.OrdinalIgnoreCase);
}
}
}

View File

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>ASP.NET Core hosting infrastructure and startup logic for web applications.</Description>
<TargetFramework>netstandard2.0</TargetFramework>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;hosting</PackageTags>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.AspNetCore.Hosting.Abstractions" />
<Reference Include="Microsoft.AspNetCore.Http.Extensions" />
<Reference Include="Microsoft.AspNetCore.Http" />
<Reference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
<Reference Include="Microsoft.Extensions.Configuration.FileExtensions" />
<Reference Include="Microsoft.Extensions.Configuration" />
<Reference Include="Microsoft.Extensions.DependencyInjection" />
<Reference Include="Microsoft.Extensions.FileProviders.Physical" />
<Reference Include="Microsoft.Extensions.Hosting.Abstractions" />
<Reference Include="Microsoft.Extensions.Logging" />
<Reference Include="Microsoft.Extensions.Options" />
<Reference Include="Microsoft.Extensions.RazorViews.Sources" PrivateAssets="All" />
<Reference Include="Microsoft.Extensions.StackTrace.Sources" PrivateAssets="All" />
<Reference Include="Microsoft.Extensions.TypeNameHelper.Sources" PrivateAssets="All" />
<Reference Include="System.Diagnostics.DiagnosticSource" />
<Reference Include="System.Reflection.Metadata" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,6 @@
// 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.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Hosting.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

View File

@ -0,0 +1,94 @@
// <auto-generated />
namespace Microsoft.AspNetCore.Hosting
{
using System.Globalization;
using System.Reflection;
using System.Resources;
internal static class Resources
{
private static readonly ResourceManager _resourceManager
= new ResourceManager("Microsoft.AspNetCore.Hosting.Resources", typeof(Resources).GetTypeInfo().Assembly);
/// <summary>
/// Internal Server Error
/// </summary>
internal static string ErrorPageHtml_Title
{
get { return GetString("ErrorPageHtml_Title"); }
}
/// <summary>
/// Internal Server Error
/// </summary>
internal static string FormatErrorPageHtml_Title()
{
return GetString("ErrorPageHtml_Title");
}
/// <summary>
/// An error occurred while starting the application.
/// </summary>
internal static string ErrorPageHtml_UnhandledException
{
get { return GetString("ErrorPageHtml_UnhandledException"); }
}
/// <summary>
/// An error occurred while starting the application.
/// </summary>
internal static string FormatErrorPageHtml_UnhandledException()
{
return GetString("ErrorPageHtml_UnhandledException");
}
/// <summary>
/// Unknown location
/// </summary>
internal static string ErrorPageHtml_UnknownLocation
{
get { return GetString("ErrorPageHtml_UnknownLocation"); }
}
/// <summary>
/// Unknown location
/// </summary>
internal static string FormatErrorPageHtml_UnknownLocation()
{
return GetString("ErrorPageHtml_UnknownLocation");
}
/// <summary>
/// WebHostBuilder allows creation only of a single instance of WebHost
/// </summary>
internal static string WebHostBuilder_SingleInstance
{
get { return GetString("WebHostBuilder_SingleInstance"); }
}
/// <summary>
/// WebHostBuilder allows creation only of a single instance of WebHost
/// </summary>
internal static string FormatWebHostBuilder_SingleInstance()
{
return GetString("WebHostBuilder_SingleInstance");
}
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);
System.Diagnostics.Debug.Assert(value != null);
if (formatterNames != null)
{
for (var i = 0; i < formatterNames.Length; i++)
{
value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
}
}
return value;
}
}
}

View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ErrorPageHtml_Title" xml:space="preserve">
<value>Internal Server Error</value>
</data>
<data name="ErrorPageHtml_UnhandledException" xml:space="preserve">
<value>An error occurred while starting the application.</value>
</data>
<data name="ErrorPageHtml_UnknownLocation" xml:space="preserve">
<value>Unknown location</value>
</data>
<data name="WebHostBuilder_SingleInstance" xml:space="preserve">
<value>WebHostBuilder allows creation only of a single instance of WebHost</value>
</data>
</root>

View File

@ -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.Collections.Generic;
namespace Microsoft.AspNetCore.Hosting.Server.Features
{
public class ServerAddressesFeature : IServerAddressesFeature
{
public ICollection<string> Addresses { get; } = new List<string>();
public bool PreferHostingUrls { get; set; }
}
}

View File

@ -0,0 +1,56 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Reflection;
using System.Runtime.ExceptionServices;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting
{
public class ConventionBasedStartup : IStartup
{
private readonly StartupMethods _methods;
public ConventionBasedStartup(StartupMethods methods)
{
_methods = methods;
}
public void Configure(IApplicationBuilder app)
{
try
{
_methods.ConfigureDelegate(app);
}
catch (Exception ex)
{
if (ex is TargetInvocationException)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
}
throw;
}
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
try
{
return _methods.ConfigureServicesDelegate(services);
}
catch (Exception ex)
{
if (ex is TargetInvocationException)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
}
throw;
}
}
}
}

View File

@ -0,0 +1,21 @@
// 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.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting
{
public class DelegateStartup : StartupBase<IServiceCollection>
{
private Action<IApplicationBuilder> _configureApp;
public DelegateStartup(IServiceProviderFactory<IServiceCollection> factory, Action<IApplicationBuilder> configureApp) : base(factory)
{
_configureApp = configureApp;
}
public override void Configure(IApplicationBuilder app) => _configureApp(app);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,162 @@
@using System
@using System.Globalization
@using System.Linq
@using System.Net
@using System.Reflection
@using Microsoft.AspNetCore.Hosting.Views
@functions
{
public ErrorPage(ErrorPageModel model)
{
Model = model;
}
public ErrorPageModel Model { get; set; }
}
@{
Response.ContentType = "text/html; charset=utf-8";
var location = string.Empty;
}
<!DOCTYPE html>
<html lang="@CultureInfo.CurrentUICulture.TwoLetterISOLanguageName" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>@Resources.ErrorPageHtml_Title</title>
<style>
<%$ include: ErrorPage.css %>
</style>
</head>
<body>
<h1>@Resources.ErrorPageHtml_UnhandledException</h1>
@foreach (var errorDetail in Model.ErrorDetails)
{
<div class="titleerror">@errorDetail.Error.GetType().Name: @{ Output.Write(HtmlEncodeAndReplaceLineBreaks(errorDetail.Error.Message)); }</div>
@{
var firstFrame = errorDetail.StackFrames.FirstOrDefault();
if (firstFrame != null)
{
location = firstFrame.Function;
}
}
if (!string.IsNullOrEmpty(location) && firstFrame != null && !string.IsNullOrEmpty(firstFrame.File))
{
<p class="location">@location in <code title="@firstFrame.File">@System.IO.Path.GetFileName(firstFrame.File)</code>, line @firstFrame.Line</p>
}
else if (!string.IsNullOrEmpty(location))
{
<p class="location">@location</p>
}
else
{
<p class="location">@Resources.ErrorPageHtml_UnknownLocation</p>
}
var reflectionTypeLoadException = errorDetail.Error as ReflectionTypeLoadException;
if (reflectionTypeLoadException != null)
{
if (reflectionTypeLoadException.LoaderExceptions.Length > 0)
{
<h3>Loader Exceptions:</h3>
<ul>
@foreach (var ex in reflectionTypeLoadException.LoaderExceptions)
{
<li>@ex.Message</li>
}
</ul>
}
}
}
<div id="stackpage" class="page">
<ul>
@{
var exceptionCount = 0;
var stackFrameCount = 0;
var exceptionDetailId = "";
var frameId = "";
}
@foreach (var errorDetail in Model.ErrorDetails)
{
@{
exceptionCount++;
exceptionDetailId = "exceptionDetail" + exceptionCount;
}
<li>
<h2 class="stackerror">@errorDetail.Error.GetType().Name: @errorDetail.Error.Message</h2>
<ul>
@foreach (var frame in errorDetail.StackFrames)
{
@{
stackFrameCount++;
frameId = "frame" + stackFrameCount;
}
<li class="frame" id="@frameId">
@if (string.IsNullOrEmpty(frame.File))
{
<h3>@frame.Function</h3>
}
else
{
<h3>@frame.Function in <code title="@frame.File">@System.IO.Path.GetFileName(frame.File)</code></h3>
}
@if (frame.Line != 0 && frame.ContextCode.Any())
{
<button class="expandCollapseButton" data-frameId="@frameId">+</button>
<div class="source">
@if (frame.PreContextCode.Any())
{
<ol start="@frame.PreContextLine" class="collapsible">
@foreach (var line in frame.PreContextCode)
{
<li><span>@line</span></li>
}
</ol>
}
<ol start="@frame.Line" class="highlight">
@foreach (var line in frame.ContextCode)
{
<li><span>@line</span></li>
}
</ol>
@if (frame.PostContextCode.Any())
{
<ol start='@(frame.Line + 1)' class="collapsible">
@foreach (var line in frame.PostContextCode)
{
<li><span>@line</span></li>
}
</ol>
}
</div>
}
</li>
}
</ul>
</li>
<li>
<br/>
<div class="rawExceptionBlock">
<div class="showRawExceptionContainer">
<button class="showRawException" data-exceptionDetailId="@exceptionDetailId">Show raw exception details</button>
</div>
<div id="@exceptionDetailId" class="rawExceptionDetails">
<pre class="rawExceptionStackTrace">@errorDetail.Error.ToString()</pre>
</div>
</div>
</li>
}
</ul>
</div>
<footer>
@Model.RuntimeDisplayName @Model.RuntimeArchitecture v@(Model.ClrVersion) &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;Microsoft.AspNetCore.Hosting version @Model.CurrentAssemblyVesion &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp; @Model.OperatingSystemDescription &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;<a href="http://go.microsoft.com/fwlink/?LinkId=517394">Need help?</a>
</footer>
<script>
//<!--
<%$ include: ErrorPage.js %>
//-->
</script>
</body>
</html>

View File

@ -0,0 +1,195 @@
body {
font-family: 'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;
font-size: .813em;
color: #222;
}
h1, h2, h3, h4, h5 {
/*font-family: 'Segoe UI',Tahoma,Arial,Helvetica,sans-serif;*/
font-weight: 100;
}
h1 {
color: #44525e;
margin: 15px 0 15px 0;
}
h2 {
margin: 10px 5px 0 0;
}
h3 {
color: #363636;
margin: 5px 5px 0 0;
}
code {
font-family: Consolas, "Courier New", courier, monospace;
}
body .titleerror {
padding: 3px 3px 6px 3px;
display: block;
font-size: 1.5em;
font-weight: 100;
}
body .location {
margin: 3px 0 10px 30px;
}
#header {
font-size: 18px;
padding: 15px 0;
border-top: 1px #ddd solid;
border-bottom: 1px #ddd solid;
margin-bottom: 0;
}
#header li {
display: inline;
margin: 5px;
padding: 5px;
color: #a0a0a0;
cursor: pointer;
}
#header .selected {
background: #44c5f2;
color: #fff;
}
#stackpage ul {
list-style: none;
padding-left: 0;
margin: 0;
/*border-bottom: 1px #ddd solid;*/
}
#stackpage .details {
font-size: 1.2em;
padding: 3px;
color: #000;
}
#stackpage .stackerror {
padding: 5px;
border-bottom: 1px #ddd solid;
}
#stackpage .frame {
padding: 0;
margin: 0 0 0 30px;
}
#stackpage .frame h3 {
padding: 2px;
margin: 0;
}
#stackpage .source {
padding: 0 0 0 30px;
}
#stackpage .source ol li {
font-family: Consolas, "Courier New", courier, monospace;
white-space: pre;
background-color: #fbfbfb;
}
#stackpage .frame .source .highlight li span {
color: #FF0000;
}
#stackpage .source ol.collapsible li {
color: #888;
}
#stackpage .source ol.collapsible li span {
color: #606060;
}
.page table {
border-collapse: separate;
border-spacing: 0;
margin: 0 0 20px;
}
.page th {
vertical-align: bottom;
padding: 10px 5px 5px 5px;
font-weight: 400;
color: #a0a0a0;
text-align: left;
}
.page td {
padding: 3px 10px;
}
.page th, .page td {
border-right: 1px #ddd solid;
border-bottom: 1px #ddd solid;
border-left: 1px transparent solid;
border-top: 1px transparent solid;
box-sizing: border-box;
}
.page th:last-child, .page td:last-child {
border-right: 1px transparent solid;
}
.page .length {
text-align: right;
}
a {
color: #1ba1e2;
text-decoration: none;
}
a:hover {
color: #13709e;
text-decoration: underline;
}
.showRawException {
cursor: pointer;
color: #44c5f2;
background-color: transparent;
font-size: 1.2em;
text-align: left;
text-decoration: none;
display: inline-block;
border: 0;
padding: 0;
}
.rawExceptionStackTrace {
font-size: 1.2em;
}
.rawExceptionBlock {
border-top: 1px #ddd solid;
border-bottom: 1px #ddd solid;
}
.showRawExceptionContainer {
margin-top: 10px;
margin-bottom: 10px;
}
.expandCollapseButton {
cursor: pointer;
float: left;
height: 16px;
width: 16px;
font-size: 10px;
position: absolute;
left: 10px;
background-color: #eee;
padding: 0;
border: 0;
margin: 0;
}

View File

@ -0,0 +1,192 @@
(function (window, undefined) {
"use strict";
function ns(selector, element) {
return new NodeCollection(selector, element);
}
function NodeCollection(selector, element) {
this.items = [];
element = element || window.document;
var nodeList;
if (typeof (selector) === "string") {
nodeList = element.querySelectorAll(selector);
for (var i = 0, l = nodeList.length; i < l; i++) {
this.items.push(nodeList.item(i));
}
}
}
NodeCollection.prototype = {
each: function (callback) {
for (var i = 0, l = this.items.length; i < l; i++) {
callback(this.items[i], i);
}
return this;
},
children: function (selector) {
var children = [];
this.each(function (el) {
children = children.concat(ns(selector, el).items);
});
return ns(children);
},
hide: function () {
this.each(function (el) {
el.style.display = "none";
});
return this;
},
toggle: function () {
this.each(function (el) {
el.style.display = el.style.display === "none" ? "" : "none";
});
return this;
},
show: function () {
this.each(function (el) {
el.style.display = "";
});
return this;
},
addClass: function (className) {
this.each(function (el) {
var existingClassName = el.className,
classNames;
if (!existingClassName) {
el.className = className;
} else {
classNames = existingClassName.split(" ");
if (classNames.indexOf(className) < 0) {
el.className = existingClassName + " " + className;
}
}
});
return this;
},
removeClass: function (className) {
this.each(function (el) {
var existingClassName = el.className,
classNames, index;
if (existingClassName === className) {
el.className = "";
} else if (existingClassName) {
classNames = existingClassName.split(" ");
index = classNames.indexOf(className);
if (index > 0) {
classNames.splice(index, 1);
el.className = classNames.join(" ");
}
}
});
return this;
},
attr: function (name) {
if (this.items.length === 0) {
return null;
}
return this.items[0].getAttribute(name);
},
on: function (eventName, handler) {
this.each(function (el, idx) {
var callback = function (e) {
e = e || window.event;
if (!e.which && e.keyCode) {
e.which = e.keyCode; // Normalize IE8 key events
}
handler.apply(el, [e]);
};
if (el.addEventListener) { // DOM Events
el.addEventListener(eventName, callback, false);
} else if (el.attachEvent) { // IE8 events
el.attachEvent("on" + eventName, callback);
} else {
el["on" + type] = callback;
}
});
return this;
},
click: function (handler) {
return this.on("click", handler);
},
keypress: function (handler) {
return this.on("keypress", handler);
}
};
function frame(el) {
ns(".source .collapsible", el).toggle();
}
function expandCollapseButton(el) {
var frameId = el.getAttribute("data-frameId");
frame(document.getElementById(frameId));
if (el.innerText === "+") {
el.innerText = "-";
}
else {
el.innerText = "+";
}
}
function tab(el) {
var unselected = ns("#header .selected").removeClass("selected").attr("id");
var selected = ns("#" + el.id).addClass("selected").attr("id");
ns("#" + unselected + "page").hide();
ns("#" + selected + "page").show();
}
ns(".rawExceptionDetails").hide();
ns(".collapsible").hide();
ns(".page").hide();
ns("#stackpage").show();
ns(".expandCollapseButton")
.click(function () {
expandCollapseButton(this);
})
.keypress(function (e) {
if (e.which === 13) {
expandCollapseButton(this);
}
});
ns("#header li")
.click(function () {
tab(this);
})
.keypress(function (e) {
if (e.which === 13) {
tab(this);
}
});
ns(".showRawException")
.click(function () {
var exceptionDetailId = this.getAttribute("data-exceptionDetailId");
ns("#" + exceptionDetailId).toggle();
});
})(window);

View File

@ -0,0 +1,29 @@
// 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.Collections.Generic;
using Microsoft.Extensions.StackTrace.Sources;
namespace Microsoft.AspNetCore.Hosting.Views
{
/// <summary>
/// Holds data to be displayed on the error page.
/// </summary>
internal class ErrorPageModel
{
/// <summary>
/// Detailed information about each exception in the stack.
/// </summary>
public IEnumerable<ExceptionDetails> ErrorDetails { get; set; }
public string RuntimeDisplayName { get; set; }
public string RuntimeArchitecture { get; set; }
public string ClrVersion { get; set; }
public string CurrentAssemblyVesion { get; set; }
public string OperatingSystemDescription { get; set; }
}
}

View File

@ -0,0 +1,50 @@
// 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.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting
{
public abstract class StartupBase : IStartup
{
public abstract void Configure(IApplicationBuilder app);
IServiceProvider IStartup.ConfigureServices(IServiceCollection services)
{
ConfigureServices(services);
return CreateServiceProvider(services);
}
public virtual void ConfigureServices(IServiceCollection services)
{
}
public virtual IServiceProvider CreateServiceProvider(IServiceCollection services)
{
return services.BuildServiceProvider();
}
}
public abstract class StartupBase<TBuilder> : StartupBase
{
private readonly IServiceProviderFactory<TBuilder> _factory;
public StartupBase(IServiceProviderFactory<TBuilder> factory)
{
_factory = factory;
}
public override IServiceProvider CreateServiceProvider(IServiceCollection services)
{
var builder = _factory.CreateBuilder(services);
ConfigureContainer(builder);
return _factory.CreateServiceProvider(builder);
}
public virtual void ConfigureContainer(TBuilder builder)
{
}
}
}

View File

@ -0,0 +1,365 @@
// 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.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.ExceptionServices;
using Microsoft.AspNetCore.Hosting.Builder;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.ObjectPool;
namespace Microsoft.AspNetCore.Hosting
{
/// <summary>
/// A builder for <see cref="IWebHost"/>
/// </summary>
public class WebHostBuilder : IWebHostBuilder
{
private readonly HostingEnvironment _hostingEnvironment;
private readonly List<Action<WebHostBuilderContext, IServiceCollection>> _configureServicesDelegates;
private IConfiguration _config;
private WebHostOptions _options;
private WebHostBuilderContext _context;
private bool _webHostBuilt;
private List<Action<WebHostBuilderContext, IConfigurationBuilder>> _configureAppConfigurationBuilderDelegates;
/// <summary>
/// Initializes a new instance of the <see cref="WebHostBuilder"/> class.
/// </summary>
public WebHostBuilder()
{
_hostingEnvironment = new HostingEnvironment();
_configureServicesDelegates = new List<Action<WebHostBuilderContext, IServiceCollection>>();
_configureAppConfigurationBuilderDelegates = new List<Action<WebHostBuilderContext, IConfigurationBuilder>>();
_config = new ConfigurationBuilder()
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
.Build();
if (string.IsNullOrEmpty(GetSetting(WebHostDefaults.EnvironmentKey)))
{
// Try adding legacy environment keys, never remove these.
UseSetting(WebHostDefaults.EnvironmentKey, Environment.GetEnvironmentVariable("Hosting:Environment")
?? Environment.GetEnvironmentVariable("ASPNET_ENV"));
}
if (string.IsNullOrEmpty(GetSetting(WebHostDefaults.ServerUrlsKey)))
{
// Try adding legacy url key, never remove this.
UseSetting(WebHostDefaults.ServerUrlsKey, Environment.GetEnvironmentVariable("ASPNETCORE_SERVER.URLS"));
}
_context = new WebHostBuilderContext
{
Configuration = _config
};
}
/// <summary>
/// Get the setting value from the configuration.
/// </summary>
/// <param name="key">The key of the setting to look up.</param>
/// <returns>The value the setting currently contains.</returns>
public string GetSetting(string key)
{
return _config[key];
}
/// <summary>
/// Add or replace a setting in the configuration.
/// </summary>
/// <param name="key">The key of the setting to add or replace.</param>
/// <param name="value">The value of the setting to add or replace.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public IWebHostBuilder UseSetting(string key, string value)
{
_config[key] = value;
return this;
}
/// <summary>
/// Adds a delegate for configuring additional services for the host or web application. This may be called
/// multiple times.
/// </summary>
/// <param name="configureServices">A delegate for configuring the <see cref="IServiceCollection"/>.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public IWebHostBuilder ConfigureServices(Action<IServiceCollection> configureServices)
{
if (configureServices == null)
{
throw new ArgumentNullException(nameof(configureServices));
}
return ConfigureServices((_, services) => configureServices(services));
}
/// <summary>
/// Adds a delegate for configuring additional services for the host or web application. This may be called
/// multiple times.
/// </summary>
/// <param name="configureServices">A delegate for configuring the <see cref="IServiceCollection"/>.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public IWebHostBuilder ConfigureServices(Action<WebHostBuilderContext, IServiceCollection> configureServices)
{
if (configureServices == null)
{
throw new ArgumentNullException(nameof(configureServices));
}
_configureServicesDelegates.Add(configureServices);
return this;
}
/// <summary>
/// Adds a delegate for configuring the <see cref="IConfigurationBuilder"/> that will construct an <see cref="IConfiguration"/>.
/// </summary>
/// <param name="configureDelegate">The delegate for configuring the <see cref="IConfigurationBuilder" /> that will be used to construct an <see cref="IConfiguration" />.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
/// <remarks>
/// The <see cref="IConfiguration"/> and <see cref="ILoggerFactory"/> on the <see cref="WebHostBuilderContext"/> are uninitialized at this stage.
/// The <see cref="IConfigurationBuilder"/> is pre-populated with the settings of the <see cref="IWebHostBuilder"/>.
/// </remarks>
public IWebHostBuilder ConfigureAppConfiguration(Action<WebHostBuilderContext, IConfigurationBuilder> configureDelegate)
{
if (configureDelegate == null)
{
throw new ArgumentNullException(nameof(configureDelegate));
}
_configureAppConfigurationBuilderDelegates.Add(configureDelegate);
return this;
}
/// <summary>
/// Builds the required services and an <see cref="IWebHost"/> which hosts a web application.
/// </summary>
public IWebHost Build()
{
if (_webHostBuilt)
{
throw new InvalidOperationException(Resources.WebHostBuilder_SingleInstance);
}
_webHostBuilt = true;
var hostingServices = BuildCommonServices(out var hostingStartupErrors);
var applicationServices = hostingServices.Clone();
var hostingServiceProvider = GetProviderFromFactory(hostingServices);
if (!_options.SuppressStatusMessages)
{
// Warn about deprecated environment variables
if (Environment.GetEnvironmentVariable("Hosting:Environment") != null)
{
Console.WriteLine("The environment variable 'Hosting:Environment' is obsolete and has been replaced with 'ASPNETCORE_ENVIRONMENT'");
}
if (Environment.GetEnvironmentVariable("ASPNET_ENV") != null)
{
Console.WriteLine("The environment variable 'ASPNET_ENV' is obsolete and has been replaced with 'ASPNETCORE_ENVIRONMENT'");
}
if (Environment.GetEnvironmentVariable("ASPNETCORE_SERVER.URLS") != null)
{
Console.WriteLine("The environment variable 'ASPNETCORE_SERVER.URLS' is obsolete and has been replaced with 'ASPNETCORE_URLS'");
}
}
AddApplicationServices(applicationServices, hostingServiceProvider);
var host = new WebHost(
applicationServices,
hostingServiceProvider,
_options,
_config,
hostingStartupErrors);
try
{
host.Initialize();
var logger = host.Services.GetRequiredService<ILogger<WebHost>>();
// Warn about duplicate HostingStartupAssemblies
foreach (var assemblyName in _options.GetFinalHostingStartupAssemblies().GroupBy(a => a, StringComparer.OrdinalIgnoreCase).Where(g => g.Count() > 1))
{
logger.LogWarning($"The assembly {assemblyName} was specified multiple times. Hosting startup assemblies should only be specified once.");
}
return host;
}
catch
{
// Dispose the host if there's a failure to initialize, this should clean up
// will dispose services that were constructed until the exception was thrown
host.Dispose();
throw;
}
IServiceProvider GetProviderFromFactory(IServiceCollection collection)
{
var provider = collection.BuildServiceProvider();
var factory = provider.GetService<IServiceProviderFactory<IServiceCollection>>();
if (factory != null && !(factory is DefaultServiceProviderFactory))
{
using (provider)
{
return factory.CreateServiceProvider(factory.CreateBuilder(collection));
}
}
return provider;
}
}
private IServiceCollection BuildCommonServices(out AggregateException hostingStartupErrors)
{
hostingStartupErrors = null;
_options = new WebHostOptions(_config, Assembly.GetEntryAssembly()?.GetName().Name);
if (!_options.PreventHostingStartup)
{
var exceptions = new List<Exception>();
// Execute the hosting startup assemblies
foreach (var assemblyName in _options.GetFinalHostingStartupAssemblies().Distinct(StringComparer.OrdinalIgnoreCase))
{
try
{
var assembly = Assembly.Load(new AssemblyName(assemblyName));
foreach (var attribute in assembly.GetCustomAttributes<HostingStartupAttribute>())
{
var hostingStartup = (IHostingStartup)Activator.CreateInstance(attribute.HostingStartupType);
hostingStartup.Configure(this);
}
}
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);
}
}
var contentRootPath = ResolveContentRootPath(_options.ContentRootPath, AppContext.BaseDirectory);
// Initialize the hosting environment
_hostingEnvironment.Initialize(contentRootPath, _options);
_context.HostingEnvironment = _hostingEnvironment;
var services = new ServiceCollection();
services.AddSingleton(_options);
services.AddSingleton<IHostingEnvironment>(_hostingEnvironment);
services.AddSingleton<Extensions.Hosting.IHostingEnvironment>(_hostingEnvironment);
services.AddSingleton(_context);
var builder = new ConfigurationBuilder()
.SetBasePath(_hostingEnvironment.ContentRootPath)
.AddConfiguration(_config);
foreach (var configureAppConfiguration in _configureAppConfigurationBuilderDelegates)
{
configureAppConfiguration(_context, builder);
}
var configuration = builder.Build();
services.AddSingleton<IConfiguration>(configuration);
_context.Configuration = configuration;
var listener = new DiagnosticListener("Microsoft.AspNetCore");
services.AddSingleton<DiagnosticListener>(listener);
services.AddSingleton<DiagnosticSource>(listener);
services.AddTransient<IApplicationBuilderFactory, ApplicationBuilderFactory>();
services.AddTransient<IHttpContextFactory, HttpContextFactory>();
services.AddScoped<IMiddlewareFactory, MiddlewareFactory>();
services.AddOptions();
services.AddLogging();
// Conjure up a RequestServices
services.AddTransient<IStartupFilter, AutoRequestServicesStartupFilter>();
services.AddTransient<IServiceProviderFactory<IServiceCollection>, DefaultServiceProviderFactory>();
// Ensure object pooling is available everywhere.
services.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
if (!string.IsNullOrEmpty(_options.StartupAssembly))
{
try
{
var startupType = StartupLoader.FindStartupType(_options.StartupAssembly, _hostingEnvironment.EnvironmentName);
if (typeof(IStartup).GetTypeInfo().IsAssignableFrom(startupType.GetTypeInfo()))
{
services.AddSingleton(typeof(IStartup), startupType);
}
else
{
services.AddSingleton(typeof(IStartup), sp =>
{
var hostingEnvironment = sp.GetRequiredService<IHostingEnvironment>();
var methods = StartupLoader.LoadMethods(sp, startupType, hostingEnvironment.EnvironmentName);
return new ConventionBasedStartup(methods);
});
}
}
catch (Exception ex)
{
var capture = ExceptionDispatchInfo.Capture(ex);
services.AddSingleton<IStartup>(_ =>
{
capture.Throw();
return null;
});
}
}
foreach (var configureServices in _configureServicesDelegates)
{
configureServices(_context, services);
}
return services;
}
private void AddApplicationServices(IServiceCollection services, IServiceProvider hostingServiceProvider)
{
// We are forwarding services from hosting container so hosting container
// can still manage their lifetime (disposal) shared instances with application services.
// NOTE: This code overrides original services lifetime. Instances would always be singleton in
// application container.
var listener = hostingServiceProvider.GetService<DiagnosticListener>();
services.Replace(ServiceDescriptor.Singleton(typeof(DiagnosticListener), listener));
services.Replace(ServiceDescriptor.Singleton(typeof(DiagnosticSource), listener));
}
private string ResolveContentRootPath(string contentRootPath, string basePath)
{
if (string.IsNullOrEmpty(contentRootPath))
{
return basePath;
}
if (Path.IsPathRooted(contentRootPath))
{
return contentRootPath;
}
return Path.Combine(Path.GetFullPath(basePath), contentRootPath);
}
}
}

View File

@ -0,0 +1,148 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Hosting
{
public static class WebHostBuilderExtensions
{
/// <summary>
/// Specify the startup method to be used to configure the web application.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="configureApp">The delegate that configures the <see cref="IApplicationBuilder"/>.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder Configure(this IWebHostBuilder hostBuilder, Action<IApplicationBuilder> configureApp)
{
if (configureApp == null)
{
throw new ArgumentNullException(nameof(configureApp));
}
var startupAssemblyName = configureApp.GetMethodInfo().DeclaringType.GetTypeInfo().Assembly.GetName().Name;
return hostBuilder
.UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName)
.ConfigureServices(services =>
{
services.AddSingleton<IStartup>(sp =>
{
return new DelegateStartup(sp.GetRequiredService<IServiceProviderFactory<IServiceCollection>>(), configureApp);
});
});
}
/// <summary>
/// Specify the startup type to be used by the web host.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="startupType">The <see cref="Type"/> to be used.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseStartup(this IWebHostBuilder hostBuilder, Type startupType)
{
var startupAssemblyName = startupType.GetTypeInfo().Assembly.GetName().Name;
return hostBuilder
.UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName)
.ConfigureServices(services =>
{
if (typeof(IStartup).GetTypeInfo().IsAssignableFrom(startupType.GetTypeInfo()))
{
services.AddSingleton(typeof(IStartup), startupType);
}
else
{
services.AddSingleton(typeof(IStartup), sp =>
{
var hostingEnvironment = sp.GetRequiredService<IHostingEnvironment>();
return new ConventionBasedStartup(StartupLoader.LoadMethods(sp, startupType, hostingEnvironment.EnvironmentName));
});
}
});
}
/// <summary>
/// Specify the startup type to be used by the web host.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <typeparam name ="TStartup">The type containing the startup methods for the application.</typeparam>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseStartup<TStartup>(this IWebHostBuilder hostBuilder) where TStartup : class
{
return hostBuilder.UseStartup(typeof(TStartup));
}
/// <summary>
/// Configures the default service provider
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="configure">A callback used to configure the <see cref="ServiceProviderOptions"/> for the default <see cref="IServiceProvider"/>.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseDefaultServiceProvider(this IWebHostBuilder hostBuilder, Action<ServiceProviderOptions> configure)
{
return hostBuilder.UseDefaultServiceProvider((context, options) => configure(options));
}
/// <summary>
/// Configures the default service provider
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="configure">A callback used to configure the <see cref="ServiceProviderOptions"/> for the default <see cref="IServiceProvider"/>.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseDefaultServiceProvider(this IWebHostBuilder hostBuilder, Action<WebHostBuilderContext, ServiceProviderOptions> configure)
{
return hostBuilder.ConfigureServices((context, services) =>
{
var options = new ServiceProviderOptions();
configure(context, options);
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<IServiceCollection>>(new DefaultServiceProviderFactory(options)));
});
}
/// <summary>
/// Adds a delegate for configuring the <see cref="IConfigurationBuilder"/> that will construct an <see cref="IConfiguration"/>.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="configureDelegate">The delegate for configuring the <see cref="IConfigurationBuilder" /> that will be used to construct an <see cref="IConfiguration" />.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
/// <remarks>
/// The <see cref="IConfiguration"/> and <see cref="ILoggerFactory"/> on the <see cref="WebHostBuilderContext"/> are uninitialized at this stage.
/// The <see cref="IConfigurationBuilder"/> is pre-populated with the settings of the <see cref="IWebHostBuilder"/>.
/// </remarks>
public static IWebHostBuilder ConfigureAppConfiguration(this IWebHostBuilder hostBuilder, Action<IConfigurationBuilder> configureDelegate)
{
return hostBuilder.ConfigureAppConfiguration((context, builder) => configureDelegate(builder));
}
/// <summary>
/// Adds a delegate for configuring the provided <see cref="ILoggingBuilder"/>. This may be called multiple times.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder" /> to configure.</param>
/// <param name="configureLogging">The delegate that configures the <see cref="ILoggingBuilder"/>.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder ConfigureLogging(this IWebHostBuilder hostBuilder, Action<ILoggingBuilder> configureLogging)
{
return hostBuilder.ConfigureServices(collection => collection.AddLogging(configureLogging));
}
/// <summary>
/// Adds a delegate for configuring the provided <see cref="LoggerFactory"/>. This may be called multiple times.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder" /> to configure.</param>
/// <param name="configureLogging">The delegate that configures the <see cref="LoggerFactory"/>.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder ConfigureLogging(this IWebHostBuilder hostBuilder, Action<WebHostBuilderContext, ILoggingBuilder> configureLogging)
{
return hostBuilder.ConfigureServices((context, collection) => collection.AddLogging(builder => configureLogging(context, builder)));
}
}
}

View File

@ -0,0 +1,187 @@
// 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.Features;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting.Internal;
namespace Microsoft.AspNetCore.Hosting
{
public static class WebHostExtensions
{
/// <summary>
/// Attempts to gracefully stop the host with the given timeout.
/// </summary>
/// <param name="host"></param>
/// <param name="timeout">The timeout for stopping gracefully. Once expired the
/// server may terminate any remaining active connections.</param>
/// <returns></returns>
public static Task StopAsync(this IWebHost host, TimeSpan timeout)
{
return host.StopAsync(new CancellationTokenSource(timeout).Token);
}
/// <summary>
/// Block the calling thread until shutdown is triggered via Ctrl+C or SIGTERM.
/// </summary>
/// <param name="host">The running <see cref="IWebHost"/>.</param>
public static void WaitForShutdown(this IWebHost host)
{
host.WaitForShutdownAsync().GetAwaiter().GetResult();
}
/// <summary>
/// Returns a Task that completes when shutdown is triggered via the given token, Ctrl+C or SIGTERM.
/// </summary>
/// <param name="host">The running <see cref="IWebHost"/>.</param>
/// <param name="token">The token to trigger shutdown.</param>
public static async Task WaitForShutdownAsync(this IWebHost host, CancellationToken token = default)
{
var done = new ManualResetEventSlim(false);
using (var cts = CancellationTokenSource.CreateLinkedTokenSource(token))
{
AttachCtrlcSigtermShutdown(cts, done, shutdownMessage: string.Empty);
try
{
await host.WaitForTokenShutdownAsync(cts.Token);
}
finally
{
done.Set();
}
}
}
/// <summary>
/// Runs a web application and block the calling thread until host shutdown.
/// </summary>
/// <param name="host">The <see cref="IWebHost"/> to run.</param>
public static void Run(this IWebHost host)
{
host.RunAsync().GetAwaiter().GetResult();
}
/// <summary>
/// Runs a web application and returns a Task that only completes when the token is triggered or shutdown is triggered.
/// </summary>
/// <param name="host">The <see cref="IWebHost"/> to run.</param>
/// <param name="token">The token to trigger shutdown.</param>
public static async Task RunAsync(this IWebHost host, CancellationToken token = default)
{
// Wait for token shutdown if it can be canceled
if (token.CanBeCanceled)
{
await host.RunAsync(token, shutdownMessage: null);
return;
}
// If token cannot be canceled, attach Ctrl+C and SIGTERM shutdown
var done = new ManualResetEventSlim(false);
using (var cts = new CancellationTokenSource())
{
var shutdownMessage = host.Services.GetRequiredService<WebHostOptions>().SuppressStatusMessages ? string.Empty : "Application is shutting down...";
AttachCtrlcSigtermShutdown(cts, done, shutdownMessage: shutdownMessage);
try
{
await host.RunAsync(cts.Token, "Application started. Press Ctrl+C to shut down.");
}
finally
{
done.Set();
}
}
}
private static async Task RunAsync(this IWebHost host, CancellationToken token, string shutdownMessage)
{
using (host)
{
await host.StartAsync(token);
var hostingEnvironment = host.Services.GetService<IHostingEnvironment>();
var options = host.Services.GetRequiredService<WebHostOptions>();
if (!options.SuppressStatusMessages)
{
Console.WriteLine($"Hosting environment: {hostingEnvironment.EnvironmentName}");
Console.WriteLine($"Content root path: {hostingEnvironment.ContentRootPath}");
var serverAddresses = host.ServerFeatures.Get<IServerAddressesFeature>()?.Addresses;
if (serverAddresses != null)
{
foreach (var address in serverAddresses)
{
Console.WriteLine($"Now listening on: {address}");
}
}
if (!string.IsNullOrEmpty(shutdownMessage))
{
Console.WriteLine(shutdownMessage);
}
}
await host.WaitForTokenShutdownAsync(token);
}
}
private static void AttachCtrlcSigtermShutdown(CancellationTokenSource cts, ManualResetEventSlim resetEvent, string shutdownMessage)
{
void Shutdown()
{
if (!cts.IsCancellationRequested)
{
if (!string.IsNullOrEmpty(shutdownMessage))
{
Console.WriteLine(shutdownMessage);
}
try
{
cts.Cancel();
}
catch (ObjectDisposedException) { }
}
// Wait on the given reset event
resetEvent.Wait();
};
AppDomain.CurrentDomain.ProcessExit += (sender, eventArgs) => Shutdown();
Console.CancelKeyPress += (sender, eventArgs) =>
{
Shutdown();
// Don't terminate the process immediately, wait for the Main thread to exit gracefully.
eventArgs.Cancel = true;
};
}
private static async Task WaitForTokenShutdownAsync(this IWebHost host, CancellationToken token)
{
var applicationLifetime = host.Services.GetService<IApplicationLifetime>();
token.Register(state =>
{
((IApplicationLifetime)state).StopApplication();
},
applicationLifetime);
var waitForStop = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
applicationLifetime.ApplicationStopping.Register(obj =>
{
var tcs = (TaskCompletionSource<object>)obj;
tcs.TrySetResult(null);
}, waitForStop);
await waitForStop.Task;
// WebHost will use its default ShutdownTimeout if none is specified.
await host.StopAsync();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,146 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>500 Internal Server Error</title>
<style type="text/css">
body {
background-color: white;
color: #111111;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 2em 4em;
}
footer a {
color: darkblue;
text-decoration: none;
font-weight: bolder;
}
#header {
margin-bottom: 2.5em;
}
.stacktrace pre {
display: inline;
}
.faded {
color: #999999;
font-weight: normal;
}
div.message {
margin-top: 2.5em;
padding: 0.3em 1em;
border-left: 0.25em solid red;
}
.light {
font-size: 1.3em;
font-weight: lighter;
}
.heavy {
font-size: 1.5em;
}
.exception {
color: red;
}
.stacktrace {
padding-top: 0.3em;
padding-left: 2em;
display: block;
font-weight: bold;
}
.codeSnippet {
margin-left: 2em;
margin-top: 1em;
margin-bottom: 1em;
display: inline-block;
border-top: 0.2em solid #cccccc;
border-bottom: 0.2em solid #cccccc;
color: black;
}
.codeSnippet div:nth-of-type(2n) {
background-color: #f0f0f0;
}
.codeSnippet div:nth-of-type(2n + 1) {
background-color: #f6f6f6;
}
.codeSnippet div.filename {
font-weight: bold;
background-color: white;
margin: 0.6em;
}
.codeSnippet div.line {
padding: 0.2em;
line-height: 1em;
}
.codeSnippet div.line .line-number {
color: #999999;
text-align: right;
margin-right: 0.5em;
}
.codeSnippet div.error {
color: red;
font-weight: bolder;
background-color: #ffeda7;
}
.codeSnippet code {
white-space: pre;
}
.rawExceptionBlock {
margin-top: 1em;
margin-left: 1em;
}
#rawException {
display: none;
}
footer {
margin-top: 2em;
font-size: smaller;
font-weight: lighter;
}
</style>
<script type="text/javascript">
function showRawException() {
var div = document.getElementById('rawException');
div.style.display = 'inline-block';
div.scrollIntoView(true);
}
</script>
</head>
<body>
<div id="header">
<div style="font-size: 6em; display: inline-block;">
:(
</div>
<div style="display: inline-block; padding-left: 3em;">
<span style="font-size: 2em;">Oops.</span><br />
<span style="font-size: 1.65em; font-weight: lighter;">500 Internal Server Error</span>
</div>
</div>
[[[0]]]
[[[1]]]
[[[2]]]
</body>
</html>

View File

@ -0,0 +1,8 @@
<div class="message">
<span class="light exception">{0}</span><br />
<span class="heavy">{1}</span><br />
{2}
<div class="stacktrace">
{3}
</div>
</div>

View File

@ -0,0 +1,3 @@
<footer>
{0} {1} v{2}&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;Microsoft.AspNetCore.Hosting version {3}&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;{4}&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;<a href="http://go.microsoft.com/fwlink/?LinkId=517394">Need help?</a>
</footer>

View File

@ -0,0 +1,3 @@
<div class="message">
<span class="heavy">{0}</span><br />
</div>

View File

@ -0,0 +1,55 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Builder.Internal;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace Microsoft.AspNetCore.Hosting.Tests
{
public class ConfigureBuilderTests
{
[Fact]
public void CapturesServiceExceptionDetails()
{
var methodInfo = GetType().GetMethod(nameof(InjectedMethod), BindingFlags.NonPublic | BindingFlags.Static);
Assert.NotNull(methodInfo);
var services = new ServiceCollection()
.AddSingleton<CrasherService>()
.BuildServiceProvider();
var applicationBuilder = new ApplicationBuilder(services);
var builder = new ConfigureBuilder(methodInfo);
Action<IApplicationBuilder> action = builder.Build(instance:null);
var ex = Assert.Throws<Exception>(() => action.Invoke(applicationBuilder));
Assert.NotNull(ex);
Assert.Equal($"Could not resolve a service of type '{typeof(CrasherService).FullName}' for the parameter"
+ $" 'service' of method '{methodInfo.Name}' on type '{methodInfo.DeclaringType.FullName}'.", ex.Message);
// the inner exception contains the root cause
Assert.NotNull(ex.InnerException);
Assert.Equal("Service instantiation failed", ex.InnerException.Message);
Assert.Contains(nameof(CrasherService), ex.InnerException.StackTrace);
}
private static void InjectedMethod(CrasherService service)
{
Assert.NotNull(service);
}
private class CrasherService
{
public CrasherService()
{
throw new Exception("Service instantiation failed");
}
}
}
}

View File

@ -0,0 +1,33 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public class CustomLoggerFactory : ILoggerFactory
{
public void CustomConfigureMethod() { }
public void AddProvider(ILoggerProvider provider) { }
public ILogger CreateLogger(string categoryName) => NullLogger.Instance;
public void Dispose() { }
}
public class SubLoggerFactory : CustomLoggerFactory { }
public class NonSubLoggerFactory : ILoggerFactory
{
public void CustomConfigureMethod() { }
public void AddProvider(ILoggerProvider provider) { }
public ILogger CreateLogger(string categoryName) => NullLogger.Instance;
public void Dispose() { }
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public class FakeOptions
{
public bool Configured { get; set; }
public string Environment { get; set; }
public string Message { get; set; }
}
}

View File

@ -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;
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public class FakeService : IFakeEveryService, IDisposable
{
public bool Disposed { get; private set; }
public void Dispose()
{
Disposed = true;
}
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public interface IFactoryService
{
IFakeService FakeService { get; }
int Value { get; }
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Hosting.Fakes
{
interface IFakeEveryService :
IFakeScopedService,
IFakeServiceInstance,
IFakeSingletonService
{
}
}

View File

@ -0,0 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public interface IFakeScopedService : IFakeService
{
}
}

View File

@ -0,0 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public interface IFakeService { }
}

View File

@ -0,0 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Hosting.Fakes
{
interface IFakeServiceInstance : IFakeService
{
}
}

View File

@ -0,0 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Hosting.Fakes
{
interface IFakeSingletonService : IFakeService
{
}
}

View File

@ -0,0 +1,10 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public interface IFakeStartupCallback
{
void ConfigurationMethodCalled(object instance);
}
}

View File

@ -0,0 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public interface INonexistentService
{
}
}

View File

@ -0,0 +1,99 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public class Startup : StartupBase
{
public Startup()
{
}
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<FakeOptions>(o => o.Configured = true);
}
public void ConfigureDevServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
o.Environment = "Dev";
});
}
public void ConfigureRetailServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
o.Environment = "Retail";
});
}
public static void ConfigureStaticServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
o.Environment = "Static";
});
}
public static IServiceProvider ConfigureStaticProviderServices()
{
var services = new ServiceCollection().AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
o.Environment = "StaticProvider";
});
return services.BuildServiceProvider();
}
public static IServiceProvider ConfigureFallbackProviderServices(IServiceProvider fallback)
{
return fallback;
}
public static IServiceProvider ConfigureNullServices()
{
return null;
}
public IServiceProvider ConfigureProviderServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
o.Environment = "Provider";
});
return services.BuildServiceProvider();
}
public IServiceProvider ConfigureProviderArgsServices()
{
var services = new ServiceCollection().AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
o.Environment = "ProviderArgs";
});
return services.BuildServiceProvider();
}
public virtual void Configure(IApplicationBuilder builder)
{
}
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public class StartupBase
{
public void ConfigureBaseClassServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
o.Environment = "BaseClass";
});
}
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public class StartupBoom
{
public StartupBoom()
{
}
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting.Fakes;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting.Tests.Fakes
{
class StartupCaseInsensitive
{
public static IServiceProvider ConfigureCaseInsensitiveServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
o.Environment = "ConfigureCaseInsensitiveServices";
});
return services.BuildServiceProvider();
}
public void ConfigureCaseInsensitive(IApplicationBuilder app)
{
}
}
}

View File

@ -0,0 +1,22 @@
// 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.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public class StartupConfigureServicesThrows
{
public void ConfigureServices(IServiceCollection services)
{
throw new Exception("Exception from ConfigureServices");
}
public void Configure(IApplicationBuilder builder)
{
}
}
}

View File

@ -0,0 +1,21 @@
// 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.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public class StartupConfigureThrows
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IApplicationBuilder builder)
{
throw new Exception("Exception from Configure");
}
}
}

View File

@ -0,0 +1,20 @@
// 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.Fakes
{
public class StartupCtorThrows
{
public StartupCtorThrows()
{
throw new Exception("Exception from constructor");
}
public void Configure(IApplicationBuilder app)
{
}
}
}

View File

@ -0,0 +1,18 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Builder;
namespace Microsoft.AspNetCore.Hosting.Fakes
{
public class StartupNoServices : Hosting.StartupBase
{
public StartupNoServices()
{
}
public override void Configure(IApplicationBuilder builder)
{
}
}
}

Some files were not shown because too many files have changed in this diff Show More