Merge branch 'release/2.1' into release/2.2
This commit is contained in:
commit
feb68c1382
|
|
@ -26,14 +26,6 @@
|
|||
path = modules/EntityFrameworkCore
|
||||
url = https://github.com/aspnet/EntityFrameworkCore.git
|
||||
branch = release/2.2
|
||||
[submodule "modules/Hosting"]
|
||||
path = modules/Hosting
|
||||
url = https://github.com/aspnet/Hosting.git
|
||||
branch = release/2.2
|
||||
[submodule "modules/HttpAbstractions"]
|
||||
path = modules/HttpAbstractions
|
||||
url = https://github.com/aspnet/HttpAbstractions.git
|
||||
branch = release/2.2
|
||||
[submodule "modules/HttpSysServer"]
|
||||
path = modules/HttpSysServer
|
||||
url = https://github.com/aspnet/HttpSysServer.git
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@
|
|||
<IncludeSource>false</IncludeSource>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
|
||||
<SharedSourceRoot>$(MSBuildThisFileDirectory)src\Shared\</SharedSourceRoot>
|
||||
|
||||
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -189,8 +189,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" />
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
|
||||
<ItemGroup>
|
||||
<RepositoryBuildOrder Include="Razor" Order="6" />
|
||||
<RepositoryBuildOrder Include="HttpAbstractions" Order="6" />
|
||||
<RepositoryBuildOrder Include="Hosting" Order="7" />
|
||||
<RepositoryBuildOrder Include="EntityFrameworkCore" Order="8" />
|
||||
<RepositoryBuildOrder Include="HttpSysServer" Order="8" />
|
||||
<RepositoryBuildOrder Include="BrowserLink" Order="8" />
|
||||
|
|
@ -36,6 +34,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>
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@
|
|||
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>2.2.0</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
|
||||
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>2.2.0</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
|
||||
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>2.2.0</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
|
||||
<MicrosoftExtensionsHostingAbstractionsPackageVersion>2.2.0</MicrosoftExtensionsHostingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsHostingPackageVersion>2.2.0</MicrosoftExtensionsHostingPackageVersion>
|
||||
<MicrosoftExtensionsHttpPackageVersion>2.2.0</MicrosoftExtensionsHttpPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.2.0</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>2.2.0</MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>
|
||||
|
|
@ -91,8 +93,11 @@
|
|||
<MicrosoftExtensionsValueStopwatchSourcesPackageVersion>2.2.0</MicrosoftExtensionsValueStopwatchSourcesPackageVersion>
|
||||
<MicrosoftExtensionsWebEncodersPackageVersion>2.2.0</MicrosoftExtensionsWebEncodersPackageVersion>
|
||||
<MicrosoftExtensionsWebEncodersSourcesPackageVersion>2.2.0</MicrosoftExtensionsWebEncodersSourcesPackageVersion>
|
||||
|
||||
<!-- These dependencies are temporary while we refactor package refs into project refs. -->
|
||||
<MicrosoftExtensionsBuffersTestingSourcesPackageVersion>2.2.0</MicrosoftExtensionsBuffersTestingSourcesPackageVersion>
|
||||
<MicrosoftExtensionsBuffersMemoryPoolSourcesPackageVersion>2.2.0</MicrosoftExtensionsBuffersMemoryPoolSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>0.6.0-rtm-final</MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>
|
||||
|
||||
<!-- 3rd party dependencies -->
|
||||
<AngleSharpPackageVersion>0.9.9</AngleSharpPackageVersion>
|
||||
|
|
|
|||
|
|
@ -46,6 +46,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)" />
|
||||
|
|
@ -74,8 +76,11 @@
|
|||
<ExternalDependency Include="Microsoft.Extensions.ValueStopwatch.Sources" Version="$(MicrosoftExtensionsValueStopwatchSourcesPackageVersion)" />
|
||||
<ExternalDependency Include="Microsoft.Extensions.WebEncoders.Sources" Version="$(MicrosoftExtensionsWebEncodersSourcesPackageVersion)" />
|
||||
<ExternalDependency Include="Microsoft.Extensions.WebEncoders" Version="$(MicrosoftExtensionsWebEncodersPackageVersion)" />
|
||||
<!-- These dependencies are temporary while we refactor package refs into project refs. -->
|
||||
<ExternalDependency Include="Microsoft.Extensions.Buffers.Testing.Sources" Version="$(MicrosoftExtensionsBuffersTestingSourcesPackageVersion)" />
|
||||
<ExternalDependency Include="Microsoft.Extensions.Buffers.MemoryPool.Sources" Version="$(MicrosoftExtensionsBuffersMemoryPoolSourcesPackageVersion)" />
|
||||
<ExternalDependency Include="Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Sources" Version="$(MicrosoftAspNetCoreHostingWebHostBuilderFactorySourcesPackageVersion)" />
|
||||
<ExternalDependency Include="Microsoft.AspNetCore.Server.IntegrationTesting" Version="$(MicrosoftAspNetCoreServerIntegrationTestingPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<SamplesProject Include="$(RepositoryRoot)src\samples\**\*.csproj;"/>
|
||||
<SamplesProject Include="$(RepositoryRoot)src\**\samples\**\*.csproj;"/>
|
||||
|
||||
<ProjectToExclude Include="@(SamplesProject)" Condition="'$(BuildSamples)' == 'false' "/>
|
||||
|
||||
|
|
@ -62,6 +62,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;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
<ItemGroup>
|
||||
<Repository Include="Scaffolding" PatchPolicy="AlwaysUpdate" />
|
||||
<Repository Include="IISIntegration" RootPath="$(RepositoryRoot)src\IISIntegration\" />
|
||||
<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" />
|
||||
|
|
@ -55,8 +55,6 @@
|
|||
<ShippedRepository Include="CORS" />
|
||||
<ShippedRepository Include="Diagnostics" />
|
||||
<ShippedRepository Include="EntityFrameworkCore" />
|
||||
<ShippedRepository Include="Hosting" />
|
||||
<ShippedRepository Include="HttpAbstractions" />
|
||||
<ShippedRepository Include="HttpSysServer" />
|
||||
<ShippedRepository Include="Identity" />
|
||||
<ShippedRepository Include="JavaScriptServices" />
|
||||
|
|
|
|||
|
|
@ -96,6 +96,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.1.1</BaselinePackageVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting.Abstractions' AND '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="[2.1.1, )" />
|
||||
</ItemGroup>
|
||||
<!-- Package: Microsoft.AspNetCore.Hosting.Server.Abstractions-->
|
||||
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting.Server.Abstractions' ">
|
||||
<BaselinePackageVersion>2.1.1</BaselinePackageVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting.Server.Abstractions' AND '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Features" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="[2.1.1, )" />
|
||||
</ItemGroup>
|
||||
<!-- Package: Microsoft.AspNetCore.Hosting.WindowsServices-->
|
||||
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting.WindowsServices' ">
|
||||
<BaselinePackageVersion>2.1.1</BaselinePackageVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting.WindowsServices' AND '$(TargetFramework)' == 'net461' ">
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.Hosting" Version="[2.1.1, )" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting.WindowsServices' AND '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.Hosting" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="System.ServiceProcess.ServiceController" Version="[4.5.0, )" />
|
||||
</ItemGroup>
|
||||
<!-- Package: Microsoft.AspNetCore.Hosting-->
|
||||
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting' ">
|
||||
<BaselinePackageVersion>2.1.1</BaselinePackageVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Hosting' AND '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.Http" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.Configuration" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.DependencyInjection" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.Logging" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.Options" Version="[2.1.1, )" />
|
||||
<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 +150,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.1.1</BaselinePackageVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http.Abstractions' AND '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Features" Version="[2.1.1, )" />
|
||||
<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.1.1</BaselinePackageVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http.Extensions' AND '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Net.Http.Headers" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.FileProviders.Abstractions" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="System.Buffers" Version="[4.5.0, )" />
|
||||
</ItemGroup>
|
||||
<!-- Package: Microsoft.AspNetCore.Http.Features-->
|
||||
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http.Features' ">
|
||||
<BaselinePackageVersion>2.1.1</BaselinePackageVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http.Features' AND '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.Primitives" Version="[2.1.1, )" />
|
||||
</ItemGroup>
|
||||
<!-- Package: Microsoft.AspNetCore.Http-->
|
||||
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http' ">
|
||||
<BaselinePackageVersion>2.1.1</BaselinePackageVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Http' AND '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Net.Http.Headers" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.ObjectPool" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.Options" Version="[2.1.1, )" />
|
||||
</ItemGroup>
|
||||
<!-- Package: Microsoft.AspNetCore.JsonPatch-->
|
||||
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.JsonPatch' ">
|
||||
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
|
||||
|
|
@ -111,6 +194,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.1.1</BaselinePackageVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Owin' AND '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.Http" Version="[2.1.1, )" />
|
||||
</ItemGroup>
|
||||
<!-- Package: Microsoft.AspNetCore.Server.Kestrel.Core-->
|
||||
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Server.Kestrel.Core' ">
|
||||
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
|
||||
|
|
@ -199,6 +289,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.1.1</BaselinePackageVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.TestHost' AND '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<BaselinePackageReference Include="Microsoft.AspNetCore.Hosting" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="System.IO.Pipelines" Version="[4.5.0, )" />
|
||||
</ItemGroup>
|
||||
<!-- Package: Microsoft.AspNetCore.WebSockets-->
|
||||
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.WebSockets' ">
|
||||
<BaselinePackageVersion>2.2.0</BaselinePackageVersion>
|
||||
|
|
@ -209,4 +307,20 @@
|
|||
<BaselinePackageReference Include="Microsoft.Extensions.Options" Version="[2.2.0, )" />
|
||||
<BaselinePackageReference Include="System.Net.WebSockets.WebSocketProtocol" Version="[4.5.1, )" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
<!-- Package: Microsoft.AspNetCore.WebUtilities-->
|
||||
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.WebUtilities' ">
|
||||
<BaselinePackageVersion>2.1.1</BaselinePackageVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.WebUtilities' AND '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<BaselinePackageReference Include="Microsoft.Net.Http.Headers" Version="[2.1.1, )" />
|
||||
<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.1.1</BaselinePackageVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.Net.Http.Headers' AND '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<BaselinePackageReference Include="Microsoft.Extensions.Primitives" Version="[2.1.1, )" />
|
||||
<BaselinePackageReference Include="System.Buffers" Version="[4.5.0, )" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -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.CommandLine" Version="$(MicrosoftExtensionsConfigurationCommandLinePackageVersion)" />
|
||||
<LatestPackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="$(MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion)" />
|
||||
|
|
@ -24,14 +25,21 @@
|
|||
<LatestPackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="$(MicrosoftExtensionsConfigurationUserSecretsPackageVersion)" />
|
||||
<LatestPackageReference Include="Microsoft.Extensions.Configuration" Version="$(MicrosoftExtensionsConfigurationPackageVersion)" />
|
||||
<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.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.Internal.AspNetCore.H2Spec.All" Version="$(MicrosoftInternalAspNetCoreH2SpecAllPackageVersion)" />
|
||||
<LatestPackageReference Include="Microsoft.NETCore.Windows.ApiSets" Version="$(MicrosoftNETCoreWindowsApiSetsPackageVersion)" />
|
||||
<LatestPackageReference Include="System.Data.SqlClient" Version="$(SystemDataSqlClientPackageVersion)" />
|
||||
<LatestPackageReference Include="System.Memory" Version="$(SystemMemoryPackageVersion)" />
|
||||
<LatestPackageReference Include="System.Net.WebSockets.WebSocketProtocol" Version="$(SystemNetWebSocketsWebSocketProtocolPackageVersion)" />
|
||||
|
|
@ -51,6 +59,8 @@
|
|||
<LatestPackageReference Include="Newtonsoft.Json" Version="11.0.2" Condition="'$(UseMSBuildJsonNet)' != 'true'" />
|
||||
<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" />
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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,9 +7,5 @@ This is required to provide dependencies for samples and tests.
|
|||
<LatestPackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="2.2.0" />
|
||||
<LatestPackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="2.2.0" />
|
||||
<LatestPackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
|
||||
<LatestPackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.0" />
|
||||
<LatestPackageReference Include="Microsoft.AspNetCore.Http.Features" Version="2.2.0" />
|
||||
<LatestPackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||
<LatestPackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -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 0724e6cde1149ee1a19bfec9c13a2c9327b71213
|
||||
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 91db78cf926939821bc96e8e60616cf5dde0b489
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
@ -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": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
// 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 HttpContext _httpContext;
|
||||
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", _httpContext.TraceIdentifier);
|
||||
}
|
||||
else if (index == 1)
|
||||
{
|
||||
return new KeyValuePair<string, object>("RequestPath", _httpContext.Request.Path.ToString());
|
||||
}
|
||||
else if (index == 2)
|
||||
{
|
||||
return new KeyValuePair<string, object>("CorrelationId", _correlationId);
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
}
|
||||
|
||||
public HostingLogScope(HttpContext httpContext, string correlationId)
|
||||
{
|
||||
_httpContext = httpContext;
|
||||
_correlationId = correlationId;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (_cachedToString == null)
|
||||
{
|
||||
_cachedToString = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"RequestId:{0} RequestPath:{1}",
|
||||
_httpContext.TraceIdentifier,
|
||||
_httpContext.Request.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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<TContainerBuilder>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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")]
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
1055
src/Hosting/Hosting/src/Startup/ExceptionPage/Views/ErrorPage.Designer.cs
generated
Normal file
1055
src/Hosting/Hosting/src/Startup/ExceptionPage/Views/ErrorPage.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -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) | Microsoft.AspNetCore.Hosting version @Model.CurrentAssemblyVesion | @Model.OperatingSystemDescription | <a href="http://go.microsoft.com/fwlink/?LinkId=517394">Need help?</a>
|
||||
</footer>
|
||||
<script>
|
||||
//<!--
|
||||
<%$ include: ErrorPage.js %>
|
||||
//-->
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,364 @@
|
|||
// 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'");
|
||||
}
|
||||
}
|
||||
|
||||
var logger = hostingServiceProvider.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.");
|
||||
}
|
||||
|
||||
AddApplicationServices(applicationServices, hostingServiceProvider);
|
||||
|
||||
var host = new WebHost(
|
||||
applicationServices,
|
||||
hostingServiceProvider,
|
||||
_options,
|
||||
_config,
|
||||
hostingStartupErrors);
|
||||
try
|
||||
{
|
||||
host.Initialize();
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
// 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);
|
||||
|
||||
await host.WaitForTokenShutdownAsync(cts.Token);
|
||||
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);
|
||||
|
||||
await host.RunAsync(cts.Token, "Application started. Press Ctrl+C to shut down.");
|
||||
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 applicationLifetime = host.Services.GetService<IApplicationLifetime>();
|
||||
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
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<footer>
|
||||
{0} {1} v{2} | Microsoft.AspNetCore.Hosting version {3} | {4} | <a href="http://go.microsoft.com/fwlink/?LinkId=517394">Need help?</a>
|
||||
</footer>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<div class="message">
|
||||
<span class="heavy">{0}</span><br />
|
||||
</div>
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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() { }
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -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 { }
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting.Fakes
|
||||
{
|
||||
public class StartupPrivateConfigure
|
||||
{
|
||||
public StartupPrivateConfigure()
|
||||
{
|
||||
}
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void Configure(IApplicationBuilder builder)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 StartupStaticCtorThrows
|
||||
{
|
||||
static StartupStaticCtorThrows()
|
||||
{
|
||||
throw new Exception("Exception from static constructor");
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue