API changes to Hosting and TestServer #525

This commit is contained in:
David Fowler 2015-12-11 13:03:43 -08:00 committed by John Luo
parent 35f9de5ae1
commit 1c70ff4d13
32 changed files with 948 additions and 709 deletions

View File

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14 # Visual Studio 14
VisualStudioVersion = 14.0.22803.0 VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E0497F39-AFFB-4819-A116-E39E361915AB}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E0497F39-AFFB-4819-A116-E39E361915AB}"
EndProject EndProject
@ -26,6 +26,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Hosting.Se
EndProject EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Server.Testing", "src\Microsoft.AspNet.Server.Testing\Microsoft.AspNet.Server.Testing.xproj", "{3DA89347-6731-4366-80C4-548F24E8607B}" Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Server.Testing", "src\Microsoft.AspNet.Server.Testing\Microsoft.AspNet.Server.Testing.xproj", "{3DA89347-6731-4366-80C4-548F24E8607B}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{9C7520A0-F2EB-411C-8BB2-80B39C937217}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SampleStartups", "samples\SampleStartups\SampleStartups.xproj", "{485B6745-7648-400A-A969-F68FCF194E46}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -112,6 +116,18 @@ Global
{3DA89347-6731-4366-80C4-548F24E8607B}.Release|Mixed Platforms.Build.0 = Release|Any CPU {3DA89347-6731-4366-80C4-548F24E8607B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{3DA89347-6731-4366-80C4-548F24E8607B}.Release|x86.ActiveCfg = Release|Any CPU {3DA89347-6731-4366-80C4-548F24E8607B}.Release|x86.ActiveCfg = Release|Any CPU
{3DA89347-6731-4366-80C4-548F24E8607B}.Release|x86.Build.0 = Release|Any CPU {3DA89347-6731-4366-80C4-548F24E8607B}.Release|x86.Build.0 = Release|Any CPU
{485B6745-7648-400A-A969-F68FCF194E46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{485B6745-7648-400A-A969-F68FCF194E46}.Debug|Any CPU.Build.0 = Debug|Any CPU
{485B6745-7648-400A-A969-F68FCF194E46}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{485B6745-7648-400A-A969-F68FCF194E46}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{485B6745-7648-400A-A969-F68FCF194E46}.Debug|x86.ActiveCfg = Debug|Any CPU
{485B6745-7648-400A-A969-F68FCF194E46}.Debug|x86.Build.0 = Debug|Any CPU
{485B6745-7648-400A-A969-F68FCF194E46}.Release|Any CPU.ActiveCfg = Release|Any CPU
{485B6745-7648-400A-A969-F68FCF194E46}.Release|Any CPU.Build.0 = Release|Any CPU
{485B6745-7648-400A-A969-F68FCF194E46}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{485B6745-7648-400A-A969-F68FCF194E46}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{485B6745-7648-400A-A969-F68FCF194E46}.Release|x86.ActiveCfg = Release|Any CPU
{485B6745-7648-400A-A969-F68FCF194E46}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -124,5 +140,6 @@ Global
{BB780FBB-7842-4759-8DE7-96FA2E5571C1} = {E0497F39-AFFB-4819-A116-E39E361915AB} {BB780FBB-7842-4759-8DE7-96FA2E5571C1} = {E0497F39-AFFB-4819-A116-E39E361915AB}
{FDBBA081-5248-4FC0-9E08-B46BEF3FA438} = {E0497F39-AFFB-4819-A116-E39E361915AB} {FDBBA081-5248-4FC0-9E08-B46BEF3FA438} = {E0497F39-AFFB-4819-A116-E39E361915AB}
{3DA89347-6731-4366-80C4-548F24E8607B} = {E0497F39-AFFB-4819-A116-E39E361915AB} {3DA89347-6731-4366-80C4-548F24E8607B} = {E0497F39-AFFB-4819-A116-E39E361915AB}
{485B6745-7648-400A-A969-F68FCF194E46} = {9C7520A0-F2EB-411C-8BB2-80B39C937217}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>485b6745-7648-400a-a969-f68fcf194e46</ProjectGuid>
<RootNamespace>SampleStartups</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<DnxInvisibleContent Include="bower.json" />
<DnxInvisibleContent Include=".bowerrc" />
<DnxInvisibleContent Include="package.json" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View File

@ -0,0 +1,44 @@
using System;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.Extensions.DependencyInjection;
// Note that this sample will not run. It is only here to illustrate usage patterns.
namespace SampleStartups
{
public class StartupBlockingOnStart
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
// Entry point for the application.
public static void Main(string[] args)
{
var config = WebApplicationConfiguration.GetDefault(args);
var application = new WebApplicationBuilder()
.UseConfiguration(config)
.UseStartup<StartupBlockingOnStart>()
.Build();
using (application.Start())
{
Console.ReadLine();
}
}
}
}

View File

@ -0,0 +1,44 @@
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.Extensions.DependencyInjection;
// Note that this sample will not run. It is only here to illustrate usage patterns.
namespace SampleStartups
{
public class StartupConfigureAddresses
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
// Entry point for the application.
public static void Main(string[] args)
{
var config = WebApplicationConfiguration.GetDefault(args);
var application = new WebApplicationBuilder()
.UseConfiguration(config)
.UseStartup<StartupConfigureAddresses>()
.Build();
var addresses = application.GetAddresses();
addresses.Add("http://localhost:5000");
addresses.Add("http://localhost:5001");
application.Run();
}
}
}

View File

@ -0,0 +1,56 @@
using System;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.Extensions.DependencyInjection;
// Note that this sample will not run. It is only here to illustrate usage patterns.
namespace SampleStartups
{
public class StartupExternallyControlled
{
private readonly IWebApplication _host;
private IDisposable _application;
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
public StartupExternallyControlled()
{
_host = new WebApplicationBuilder().UseStartup<StartupExternallyControlled>().Build();
// Clear all configured addresses
_host.GetAddresses().Clear();
}
public void Start()
{
_application = _host.Start();
}
public void Stop()
{
_application.Dispose();
}
public void AddUrl(string url)
{
var addresses = _host.GetAddresses();
addresses.Add(url);
}
}
}

View File

@ -0,0 +1,68 @@
using System;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
// Note that this sample will not run. It is only here to illustrate usage patterns.
namespace SampleStartups
{
public class StartupFullControl
{
public static void Main(string[] args)
{
var application = new WebApplicationBuilder()
.UseServerFactory("Microsoft.AspNet.Server.Kestrel") // Set the server manually
.UseEnvironment("Development")
.UseWebRoot("public")
.ConfigureLogging(loggerFactory =>
{
loggerFactory.AddProvider(new MyHostLoggerProvider());
})
.ConfigureServices(services =>
{
// Configure services that the application can see
services.AddSingleton<IMyCustomService, MyCustomService>();
})
.Configure(app =>
{
// Write the application inline, this won't call any startup class in the assembly
app.Use(next => context =>
{
return next(context);
});
})
.Build();
application.Run();
}
}
public class MyHostLoggerProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName)
{
throw new NotImplementedException();
}
public void Dispose()
{
throw new NotImplementedException();
}
}
public interface IMyCustomService
{
void Go();
}
public class MyCustomService : IMyCustomService
{
public void Go()
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,40 @@
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.Extensions.DependencyInjection;
// Note that this sample will not run. It is only here to illustrate usage patterns.
namespace SampleStartups
{
public class StartupHelloWorld
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
// Entry point for the application.
public static void Main(string[] args)
{
var config = WebApplicationConfiguration.GetDefault(args);
var application = new WebApplicationBuilder()
.UseConfiguration(config)
.UseStartup<StartupHelloWorld>()
.Build();
application.Run();
}
}
}

View File

@ -0,0 +1,10 @@
{
"version": "1.0.0-*",
"dependencies": {
"Microsoft.AspNet.Hosting": "1.0.0-*"
},
"frameworks": {
"dnx451": { },
"dnxcore50": { }
}
}

View File

@ -0,0 +1,30 @@
// 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.AspNet.Http.Features;
namespace Microsoft.AspNet.Hosting
{
/// <summary>
/// Represents a configured web application
/// </summary>
public interface IWebApplication
{
/// <summary>
/// The <see cref="IFeatureCollection"/> exposed by the configured server.
/// </summary>
IFeatureCollection ServerFeatures { get; }
/// <summary>
/// The <see cref="IServiceProvider"/> for the application.
/// </summary>
IServiceProvider Services { get; }
/// <summary>
/// Starts listening on the configured addresses.
/// </summary>
/// <returns></returns>
IDisposable Start();
}
}

View File

@ -1,37 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNet.Http.Features;
namespace Microsoft.AspNet.Hosting.Internal
{
public class Application : IApplication
{
private readonly IDisposable _stop;
private readonly IServiceProvider _services;
private readonly IFeatureCollection _server;
public Application(IServiceProvider services, IFeatureCollection server, IDisposable stop)
{
_services = services;
_server = server;
_stop = stop;
}
public IFeatureCollection ServerFeatures
{
get { return _server; }
}
public IServiceProvider Services
{
get { return _services; }
}
public void Dispose()
{
_stop.Dispose();
}
}
}

View File

@ -4,7 +4,7 @@
using System; using System;
using System.Threading; using System.Threading;
namespace Microsoft.AspNet.Hosting namespace Microsoft.AspNet.Hosting.Internal
{ {
/// <summary> /// <summary>
/// Allows consumers to perform cleanup during a graceful shutdown. /// Allows consumers to perform cleanup during a graceful shutdown.

View File

@ -4,7 +4,7 @@
using Microsoft.AspNet.FileProviders; using Microsoft.AspNet.FileProviders;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
namespace Microsoft.AspNet.Hosting namespace Microsoft.AspNet.Hosting.Internal
{ {
public class HostingEnvironment : IHostingEnvironment public class HostingEnvironment : IHostingEnvironment
{ {

View File

@ -7,11 +7,11 @@ using Microsoft.AspNet.FileProviders;
using Microsoft.AspNet.Hosting.Internal; using Microsoft.AspNet.Hosting.Internal;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
namespace Microsoft.AspNet.Hosting namespace Microsoft.AspNet.Hosting.Internal
{ {
public static class HostingEnvironmentExtensions public static class HostingEnvironmentExtensions
{ {
public static void Initialize(this IHostingEnvironment hostingEnvironment, string applicationBasePath, WebHostOptions options, IConfiguration configuration) public static void Initialize(this IHostingEnvironment hostingEnvironment, string applicationBasePath, WebApplicationOptions options, IConfiguration configuration)
{ {
if (options == null) if (options == null)
{ {

View File

@ -1,15 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNet.Http.Features;
namespace Microsoft.AspNet.Hosting.Internal
{
public interface IApplication : IDisposable
{
IFeatureCollection ServerFeatures { get; }
IServiceProvider Services { get; }
}
}

View File

@ -1,15 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNet.Hosting.Internal
{
public interface IHostingEngine
{
IApplication Start();
// Accessing this will block Use methods
IServiceProvider ApplicationServices { get; }
}
}

View File

@ -19,7 +19,7 @@ using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.AspNet.Hosting.Internal namespace Microsoft.AspNet.Hosting.Internal
{ {
public class HostingEngine : IHostingEngine public class WebApplication : IWebApplication
{ {
// This is defined by IIS's HttpPlatformHandler. // This is defined by IIS's HttpPlatformHandler.
private static readonly string ServerPort = "HTTP_PLATFORM_PORT"; private static readonly string ServerPort = "HTTP_PLATFORM_PORT";
@ -27,11 +27,11 @@ namespace Microsoft.AspNet.Hosting.Internal
private readonly IServiceCollection _applicationServiceCollection; private readonly IServiceCollection _applicationServiceCollection;
private readonly IStartupLoader _startupLoader; private readonly IStartupLoader _startupLoader;
private readonly ApplicationLifetime _applicationLifetime; private readonly ApplicationLifetime _applicationLifetime;
private readonly WebHostOptions _options; private readonly WebApplicationOptions _options;
private readonly IConfiguration _config; private readonly IConfiguration _config;
private readonly bool _captureStartupErrors;
private IServiceProvider _applicationServices; private IServiceProvider _applicationServices;
private RequestDelegate _application;
// Only one of these should be set // Only one of these should be set
internal string StartupAssemblyName { get; set; } internal string StartupAssemblyName { get; set; }
@ -43,12 +43,11 @@ namespace Microsoft.AspNet.Hosting.Internal
internal string ServerFactoryLocation { get; set; } internal string ServerFactoryLocation { get; set; }
internal IServer Server { get; set; } internal IServer Server { get; set; }
public HostingEngine( public WebApplication(
IServiceCollection appServices, IServiceCollection appServices,
IStartupLoader startupLoader, IStartupLoader startupLoader,
WebHostOptions options, WebApplicationOptions options,
IConfiguration config, IConfiguration config)
bool captureStartupErrors)
{ {
if (appServices == null) if (appServices == null)
{ {
@ -69,12 +68,11 @@ namespace Microsoft.AspNet.Hosting.Internal
_options = options; _options = options;
_applicationServiceCollection = appServices; _applicationServiceCollection = appServices;
_startupLoader = startupLoader; _startupLoader = startupLoader;
_captureStartupErrors = captureStartupErrors;
_applicationLifetime = new ApplicationLifetime(); _applicationLifetime = new ApplicationLifetime();
_applicationServiceCollection.AddSingleton<IApplicationLifetime>(_applicationLifetime); _applicationServiceCollection.AddSingleton<IApplicationLifetime>(_applicationLifetime);
} }
public IServiceProvider ApplicationServices public IServiceProvider Services
{ {
get get
{ {
@ -83,29 +81,45 @@ namespace Microsoft.AspNet.Hosting.Internal
} }
} }
public virtual IApplication Start() public IFeatureCollection ServerFeatures
{ {
var application = BuildApplication(); get
{
return Server?.Features;
}
}
var logger = _applicationServices.GetRequiredService<ILogger<HostingEngine>>(); public void Initialize()
{
if (_application == null)
{
_application = BuildApplication();
}
}
public virtual IDisposable Start()
{
Initialize();
var logger = _applicationServices.GetRequiredService<ILogger<WebApplication>>();
var diagnosticSource = _applicationServices.GetRequiredService<DiagnosticSource>(); var diagnosticSource = _applicationServices.GetRequiredService<DiagnosticSource>();
var httpContextFactory = _applicationServices.GetRequiredService<IHttpContextFactory>(); var httpContextFactory = _applicationServices.GetRequiredService<IHttpContextFactory>();
logger.Starting(); logger.Starting();
Server.Start(new HostingApplication(application, logger, diagnosticSource, httpContextFactory)); Server.Start(new HostingApplication(_application, logger, diagnosticSource, httpContextFactory));
_applicationLifetime.NotifyStarted(); _applicationLifetime.NotifyStarted();
logger.Started(); logger.Started();
return new Application(ApplicationServices, Server.Features, new Disposable(() => return new Disposable(() =>
{ {
logger.Shutdown(); logger.Shutdown();
_applicationLifetime.StopApplication(); _applicationLifetime.StopApplication();
Server.Dispose(); Server.Dispose();
_applicationLifetime.NotifyStopped(); _applicationLifetime.NotifyStopped();
(_applicationServices as IDisposable)?.Dispose(); (_applicationServices as IDisposable)?.Dispose();
})); });
} }
private void EnsureApplicationServices() private void EnsureApplicationServices()
@ -168,7 +182,7 @@ namespace Microsoft.AspNet.Hosting.Internal
return builder.Build(); return builder.Build();
} }
catch (Exception ex) when (_captureStartupErrors) catch (Exception ex) when (_options.CaptureStartupErrors)
{ {
// EnsureApplicationServices may have failed due to a missing or throwing Startup class. // EnsureApplicationServices may have failed due to a missing or throwing Startup class.
if (_applicationServices == null) if (_applicationServices == null)
@ -180,7 +194,7 @@ namespace Microsoft.AspNet.Hosting.Internal
// Write errors to standard out so they can be retrieved when not in development mode. // Write errors to standard out so they can be retrieved when not in development mode.
Console.Out.WriteLine("Application startup exception: " + ex.ToString()); Console.Out.WriteLine("Application startup exception: " + ex.ToString());
var logger = _applicationServices.GetRequiredService<ILogger<HostingEngine>>(); var logger = _applicationServices.GetRequiredService<ILogger<WebApplication>>();
logger.ApplicationError(ex); logger.ApplicationError(ex);
// Generate an HTML error page. // Generate an HTML error page.

View File

@ -0,0 +1,50 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Configuration;
namespace Microsoft.AspNet.Hosting.Internal
{
public class WebApplicationOptions
{
private const string OldEnvironmentKey = "ENV";
public WebApplicationOptions()
{
}
public WebApplicationOptions(IConfiguration configuration)
{
if (configuration == null)
{
throw new ArgumentNullException(nameof(configuration));
}
Application = configuration[WebApplicationConfiguration.ApplicationKey];
DetailedErrors = ParseBool(configuration, WebApplicationConfiguration.DetailedErrorsKey);
CaptureStartupErrors = ParseBool(configuration, WebApplicationConfiguration.CaptureStartupErrorsKey);
Environment = configuration[WebApplicationConfiguration.EnvironmentKey] ?? configuration[OldEnvironmentKey];
ServerFactoryLocation = configuration[WebApplicationConfiguration.ServerKey];
WebRoot = configuration[WebApplicationConfiguration.WebRootKey];
}
public string Application { get; set; }
public bool DetailedErrors { get; set; }
public bool CaptureStartupErrors { get; set; }
public string Environment { get; set; }
public string ServerFactoryLocation { get; set; }
public string WebRoot { get; set; }
private static bool ParseBool(IConfiguration configuration, string key)
{
return string.Equals("true", configuration[key], StringComparison.OrdinalIgnoreCase)
|| string.Equals("1", configuration[key], StringComparison.OrdinalIgnoreCase);
}
}
}

View File

@ -1,13 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNet.Hosting
{
public class Program
{
public static void Main(string[] args)
{
WebApplication.Run(args);
}
}
}

View File

@ -1,93 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Server.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNet.Hosting
{
public class WebApplication
{
private const string HostingJsonFile = "hosting.json";
private const string EnvironmentVariablesPrefix = "ASPNET_";
private const string ConfigFileKey = "config";
public static void Run(string[] args)
{
Run(startupType: null, args: args);
}
public static void Run<TStartup>()
{
Run(typeof(TStartup), null);
}
public static void Run<TStartup>(string[] args)
{
Run(typeof(TStartup), args);
}
public static void Run(Type startupType)
{
Run(startupType, null);
}
public static void Run(Type startupType, string[] args)
{
// Allow the location of the json file to be specified via a --config command line arg
var tempBuilder = new ConfigurationBuilder().AddCommandLine(args);
var tempConfig = tempBuilder.Build();
var configFilePath = tempConfig[ConfigFileKey] ?? HostingJsonFile;
var config = LoadHostingConfiguration(configFilePath, args);
var hostBuilder = new WebHostBuilder(config, captureStartupErrors: true);
if (startupType != null)
{
hostBuilder.UseStartup(startupType);
}
var host = hostBuilder.Build();
using (var app = host.Start())
{
var hostingEnv = app.Services.GetRequiredService<IHostingEnvironment>();
Console.WriteLine("Hosting environment: " + hostingEnv.EnvironmentName);
var serverAddresses = app.ServerFeatures.Get<IServerAddressesFeature>();
if (serverAddresses != null)
{
foreach (var address in serverAddresses.Addresses)
{
Console.WriteLine("Now listening on: " + address);
}
}
Console.WriteLine("Application started. Press Ctrl+C to shut down.");
var appLifetime = app.Services.GetRequiredService<IApplicationLifetime>();
Console.CancelKeyPress += (sender, eventArgs) =>
{
appLifetime.StopApplication();
// Don't terminate the process immediately, wait for the Main thread to exit gracefully.
eventArgs.Cancel = true;
};
appLifetime.ApplicationStopping.WaitHandle.WaitOne();
}
}
internal static IConfiguration LoadHostingConfiguration(string configJsonPath, string[] args)
{
// We are adding all environment variables first and then adding the ASPNET_ ones
// with the prefix removed to unify with the command line and config file formats
return new ConfigurationBuilder()
.AddJsonFile(configJsonPath, optional: true)
.AddEnvironmentVariables()
.AddEnvironmentVariables(prefix: EnvironmentVariablesPrefix)
.AddCommandLine(args)
.Build();
}
}
}

View File

@ -18,49 +18,180 @@ using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.AspNet.Hosting namespace Microsoft.AspNet.Hosting
{ {
public class WebHostBuilder public class WebApplicationBuilder
{ {
private readonly IHostingEnvironment _hostingEnvironment; private readonly IHostingEnvironment _hostingEnvironment;
private readonly ILoggerFactory _loggerFactory; private readonly ILoggerFactory _loggerFactory;
private readonly IConfiguration _config;
private readonly WebHostOptions _options; private IConfiguration _config;
private WebApplicationOptions _options;
private Action<IServiceCollection> _configureServices; private Action<IServiceCollection> _configureServices;
private string _environmentName; private string _environmentName;
private string _webRoot;
// Only one of these should be set // Only one of these should be set
private StartupMethods _startup; private StartupMethods _startup;
private Type _startupType; private Type _startupType;
private string _startupAssemblyName; private string _startupAssemblyName;
private readonly bool _captureStartupErrors;
// Only one of these should be set // Only one of these should be set
private string _serverFactoryLocation; private string _serverFactoryLocation;
private IServerFactory _serverFactory; private IServerFactory _serverFactory;
private IServer _server; private IServer _server;
public WebHostBuilder() public WebApplicationBuilder()
: this(config: new ConfigurationBuilder().Build())
{ {
}
public WebHostBuilder(IConfiguration config)
: this(config: config, captureStartupErrors: false)
{
}
public WebHostBuilder(IConfiguration config, bool captureStartupErrors)
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
_hostingEnvironment = new HostingEnvironment(); _hostingEnvironment = new HostingEnvironment();
_loggerFactory = new LoggerFactory(); _loggerFactory = new LoggerFactory();
_config = config; }
_options = new WebHostOptions(config);
_captureStartupErrors = captureStartupErrors; public WebApplicationBuilder UseConfiguration(IConfiguration configuration)
{
_config = configuration;
return this;
}
public WebApplicationBuilder UseEnvironment(string environment)
{
if (environment == null)
{
throw new ArgumentNullException(nameof(environment));
}
_environmentName = environment;
return this;
}
public WebApplicationBuilder UseWebRoot(string webRoot)
{
if (webRoot == null)
{
throw new ArgumentNullException(nameof(webRoot));
}
_webRoot = webRoot;
return this;
}
public WebApplicationBuilder UseServer(IServer server)
{
if (server == null)
{
throw new ArgumentNullException(nameof(server));
}
_server = server;
return this;
}
public WebApplicationBuilder UseServerFactory(string assemblyName)
{
if (assemblyName == null)
{
throw new ArgumentNullException(nameof(assemblyName));
}
_serverFactoryLocation = assemblyName;
return this;
}
public WebApplicationBuilder UseServerFactory(IServerFactory factory)
{
if (factory == null)
{
throw new ArgumentNullException(nameof(factory));
}
_serverFactory = factory;
return this;
}
public WebApplicationBuilder UseStartup(string startupAssemblyName)
{
if (startupAssemblyName == null)
{
throw new ArgumentNullException(nameof(startupAssemblyName));
}
_startupAssemblyName = startupAssemblyName;
return this;
}
public WebApplicationBuilder UseStartup(Type startupType)
{
if (startupType == null)
{
throw new ArgumentNullException(nameof(startupType));
}
_startupType = startupType;
return this;
}
public WebApplicationBuilder UseStartup<TStartup>() where TStartup : class
{
return UseStartup(typeof(TStartup));
}
public WebApplicationBuilder ConfigureServices(Action<IServiceCollection> configureServices)
{
_configureServices = configureServices;
return this;
}
public WebApplicationBuilder Configure(Action<IApplicationBuilder> configureApp)
{
if (configureApp == null)
{
throw new ArgumentNullException(nameof(configureApp));
}
_startup = new StartupMethods(configureApp);
return this;
}
public WebApplicationBuilder ConfigureLogging(Action<ILoggerFactory> configureLogging)
{
configureLogging(_loggerFactory);
return this;
}
public IWebApplication Build()
{
var hostingServices = BuildHostingServices();
var hostingContainer = hostingServices.BuildServiceProvider();
var appEnvironment = hostingContainer.GetRequiredService<IApplicationEnvironment>();
var startupLoader = hostingContainer.GetRequiredService<IStartupLoader>();
_config = _config ?? WebApplicationConfiguration.GetDefault();
_options = new WebApplicationOptions(_config);
// Initialize the hosting environment
_options.WebRoot = _webRoot ?? _options.WebRoot;
_hostingEnvironment.Initialize(appEnvironment.ApplicationBasePath, _options, _config);
if (!string.IsNullOrEmpty(_environmentName))
{
_hostingEnvironment.EnvironmentName = _environmentName;
}
var application = new WebApplication(hostingServices, startupLoader, _options, _config);
// Only one of these should be set, but they are used in priority
application.Server = _server;
application.ServerFactory = _serverFactory;
application.ServerFactoryLocation = _options.ServerFactoryLocation ?? _serverFactoryLocation;
// Only one of these should be set, but they are used in priority
application.Startup = _startup;
application.StartupType = _startupType;
application.StartupAssemblyName = _startupAssemblyName ?? _options.Application;
application.Initialize();
return application;
} }
private IServiceCollection BuildHostingServices() private IServiceCollection BuildHostingServices()
@ -83,11 +214,6 @@ namespace Microsoft.AspNet.Hosting
// Conjure up a RequestServices // Conjure up a RequestServices
services.AddTransient<IStartupFilter, AutoRequestServicesStartupFilter>(); services.AddTransient<IStartupFilter, AutoRequestServicesStartupFilter>();
if (_configureServices != null)
{
_configureServices(services);
}
var defaultPlatformServices = PlatformServices.Default; var defaultPlatformServices = PlatformServices.Default;
if (defaultPlatformServices != null) if (defaultPlatformServices != null)
{ {
@ -102,153 +228,12 @@ namespace Microsoft.AspNet.Hosting
} }
} }
if (_configureServices != null)
{
_configureServices(services);
}
return services; return services;
} }
public IHostingEngine Build()
{
var hostingServices = BuildHostingServices();
var hostingContainer = hostingServices.BuildServiceProvider();
var appEnvironment = hostingContainer.GetRequiredService<IApplicationEnvironment>();
var startupLoader = hostingContainer.GetRequiredService<IStartupLoader>();
_hostingEnvironment.Initialize(appEnvironment.ApplicationBasePath, _options, _config);
if (!string.IsNullOrEmpty(_environmentName))
{
_hostingEnvironment.EnvironmentName = _environmentName;
}
var engine = new HostingEngine(hostingServices, startupLoader, _options, _config, _captureStartupErrors);
// Only one of these should be set, but they are used in priority
engine.Server = _server;
engine.ServerFactory = _serverFactory;
engine.ServerFactoryLocation = _options.Server ?? _serverFactoryLocation;
// Only one of these should be set, but they are used in priority
engine.Startup = _startup;
engine.StartupType = _startupType;
engine.StartupAssemblyName = _startupAssemblyName ?? _options.Application ?? appEnvironment.ApplicationName;
return engine;
}
public WebHostBuilder UseServices(Action<IServiceCollection> configureServices)
{
_configureServices = configureServices;
return this;
}
public WebHostBuilder UseEnvironment(string environment)
{
if (environment == null)
{
throw new ArgumentNullException(nameof(environment));
}
_environmentName = environment;
return this;
}
public WebHostBuilder UseServer(IServer server)
{
if (server == null)
{
throw new ArgumentNullException(nameof(server));
}
_server = server;
return this;
}
public WebHostBuilder UseServerFactory(string assemblyName)
{
if (assemblyName == null)
{
throw new ArgumentNullException(nameof(assemblyName));
}
_serverFactoryLocation = assemblyName;
return this;
}
public WebHostBuilder UseServerFactory(IServerFactory factory)
{
if (factory == null)
{
throw new ArgumentNullException(nameof(factory));
}
_serverFactory = factory;
return this;
}
public WebHostBuilder UseStartup(string startupAssemblyName)
{
if (startupAssemblyName == null)
{
throw new ArgumentNullException(nameof(startupAssemblyName));
}
_startupAssemblyName = startupAssemblyName;
return this;
}
public WebHostBuilder UseStartup(Type startupType)
{
if (startupType == null)
{
throw new ArgumentNullException(nameof(startupType));
}
_startupType = startupType;
return this;
}
public WebHostBuilder UseStartup<TStartup>() where TStartup : class
{
return UseStartup(typeof(TStartup));
}
public WebHostBuilder UseStartup(Action<IApplicationBuilder> configureApp)
{
if (configureApp == null)
{
throw new ArgumentNullException(nameof(configureApp));
}
return UseStartup(configureApp, configureServices: null);
}
public WebHostBuilder UseStartup(Action<IApplicationBuilder> configureApp, Func<IServiceCollection, IServiceProvider> configureServices)
{
if (configureApp == null)
{
throw new ArgumentNullException(nameof(configureApp));
}
_startup = new StartupMethods(configureApp, configureServices);
return this;
}
public WebHostBuilder UseStartup(Action<IApplicationBuilder> configureApp, Action<IServiceCollection> configureServices)
{
if (configureApp == null)
{
throw new ArgumentNullException(nameof(configureApp));
}
_startup = new StartupMethods(configureApp,
services =>
{
if (configureServices != null)
{
configureServices(services);
}
return services.BuildServiceProvider();
});
return this;
}
} }
} }

View File

@ -0,0 +1,40 @@
using Microsoft.Extensions.Configuration;
namespace Microsoft.AspNet.Hosting
{
public class WebApplicationConfiguration
{
public static readonly string ApplicationKey = "app";
public static readonly string DetailedErrorsKey = "detailedErrors";
public static readonly string EnvironmentKey = "environment";
public static readonly string ServerKey = "server";
public static readonly string WebRootKey = "webroot";
public static readonly string CaptureStartupErrorsKey = "captureStartupErrors";
public static readonly string HostingJsonFile = "hosting.json";
public static readonly string EnvironmentVariablesPrefix = "ASPNET_";
public static IConfiguration GetDefault()
{
return GetDefault(args: null);
}
public static IConfiguration GetDefault(string[] args)
{
// We are adding all environment variables first and then adding the ASPNET_ ones
// with the prefix removed to unify with the command line and config file formats
var configBuilder = new ConfigurationBuilder()
.AddJsonFile(HostingJsonFile, optional: true)
.AddEnvironmentVariables()
.AddEnvironmentVariables(prefix: EnvironmentVariablesPrefix);
if (args != null)
{
configBuilder.AddCommandLine(args);
}
return configBuilder.Build();
}
}
}

View File

@ -0,0 +1,60 @@
// 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 Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Server.Features;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNet.Hosting
{
public static class WebApplicationExtensions
{
/// <summary>
/// Retruns the server addresses the web application is going to listen on.
/// </summary>
/// <param name="application"></param>
/// <returns>An <see cref="ICollection{string}"> which the addresses the server will listen to</returns>
public static ICollection<string> GetAddresses(this IWebApplication application)
{
return application.ServerFeatures.Get<IServerAddressesFeature>()?.Addresses;
}
/// <summary>
/// Runs a web application and block the calling thread until host shutdown.
/// </summary>
/// <param name="application"></param>
public static void Run(this IWebApplication application)
{
using (application.Start())
{
var hostingEnvironment = application.Services.GetService<IHostingEnvironment>();
var applicationLifetime = application.Services.GetService<IApplicationLifetime>();
Console.WriteLine("Hosting environment: " + hostingEnvironment.EnvironmentName);
var serverAddresses = application.GetAddresses();
if (serverAddresses != null)
{
foreach (var address in serverAddresses)
{
Console.WriteLine("Now listening on: " + address);
}
}
Console.WriteLine("Application started. Press Ctrl+C to shut down.");
Console.CancelKeyPress += (sender, eventArgs) =>
{
applicationLifetime.StopApplication();
// Don't terminate the process immediately, wait for the Main thread to exit gracefully.
eventArgs.Cancel = true;
};
applicationLifetime.ApplicationStopping.WaitHandle.WaitOne();
}
}
}
}

View File

@ -1,47 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Configuration;
namespace Microsoft.AspNet.Hosting
{
public class WebHostOptions
{
private const string ApplicationKey = "app";
private const string DetailedErrorsKey = "detailedErrors";
private const string EnvironmentKey = "environment";
private const string ServerKey = "server";
private const string WebRootKey = "webroot";
private const string OldEnvironmentKey = "ENV";
public WebHostOptions()
{
}
public WebHostOptions(IConfiguration configuration)
{
if (configuration == null)
{
throw new ArgumentNullException(nameof(configuration));
}
Application = configuration[ApplicationKey];
DetailedErrors = string.Equals("true", configuration[DetailedErrorsKey], StringComparison.OrdinalIgnoreCase)
|| string.Equals("1", configuration[DetailedErrorsKey], StringComparison.OrdinalIgnoreCase);
Environment = configuration[EnvironmentKey] ?? configuration[OldEnvironmentKey];
Server = configuration[ServerKey];
WebRoot = configuration[WebRootKey];
}
public string Application { get; set; }
public bool DetailedErrors { get; set; }
public string Environment { get; set; }
public string Server { get; set; }
public string WebRoot { get; set; }
}
}

View File

@ -4,13 +4,10 @@
using System; using System;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Hosting.Server; using Microsoft.AspNet.Hosting.Server;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Features; using Microsoft.AspNet.Http.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Context = Microsoft.AspNet.Hosting.Internal.HostingApplication.Context; using Context = Microsoft.AspNet.Hosting.Internal.HostingApplication.Context;
namespace Microsoft.AspNet.TestHost namespace Microsoft.AspNet.TestHost
@ -23,78 +20,16 @@ namespace Microsoft.AspNet.TestHost
private bool _disposed = false; private bool _disposed = false;
private IHttpApplication<Context> _application; private IHttpApplication<Context> _application;
public TestServer(WebHostBuilder builder) public TestServer(WebApplicationBuilder builder)
{ {
var hostingEngine = builder.UseServer(this).Build(); var application = builder.UseServer(this).Build();
_appInstance = hostingEngine.Start(); _appInstance = application.Start();
} }
public Uri BaseAddress { get; set; } = new Uri("http://localhost/"); public Uri BaseAddress { get; set; } = new Uri("http://localhost/");
IFeatureCollection IServer.Features { get; } IFeatureCollection IServer.Features { get; }
public static TestServer Create()
{
return Create(config: null, configureApp: null, configureServices: null);
}
public static TestServer Create(Action<IApplicationBuilder> configureApp)
{
return Create(config: null, configureApp: configureApp, configureServices: null);
}
public static TestServer Create(Action<IApplicationBuilder> configureApp, Action<IServiceCollection> configureServices)
{
return Create(config: null, configureApp: configureApp, configureServices: configureServices);
}
public static TestServer Create(Action<IApplicationBuilder> configureApp, Func<IServiceCollection, IServiceProvider> configureServices)
{
return new TestServer(CreateBuilder(config: null, configureApp: configureApp, configureServices: configureServices, configureHostServices: null));
}
public static TestServer Create(Action<IApplicationBuilder> configureApp, Func<IServiceCollection, IServiceProvider> configureServices, Action<IServiceCollection> configureHostServices)
{
return new TestServer(CreateBuilder(config: null, configureApp: configureApp, configureServices: configureServices, configureHostServices: configureHostServices));
}
public static TestServer Create(IConfiguration config, Action<IApplicationBuilder> configureApp, Action<IServiceCollection> configureServices)
{
return new TestServer(CreateBuilder(config, configureApp, configureServices));
}
public static WebHostBuilder CreateBuilder(IConfiguration config, Action<IApplicationBuilder> configureApp, Action<IServiceCollection> configureServices)
{
return CreateBuilder(config, configureApp,
s =>
{
if (configureServices != null)
{
configureServices(s);
}
return s.BuildServiceProvider();
}, null);
}
public static WebHostBuilder CreateBuilder(IConfiguration config, Action<IApplicationBuilder> configureApp, Func<IServiceCollection, IServiceProvider> configureServices)
{
return CreateBuilder(config, configureApp, configureServices, null);
}
public static WebHostBuilder CreateBuilder(IConfiguration config, Action<IApplicationBuilder> configureApp, Func<IServiceCollection, IServiceProvider> configureServices, Action<IServiceCollection> configureHostServices)
{
return CreateBuilder(config).UseStartup(configureApp, configureServices).UseServices(configureHostServices);
}
public static WebHostBuilder CreateBuilder(IConfiguration config)
{
return new WebHostBuilder(
config ?? new ConfigurationBuilder().Build());
}
public static WebHostBuilder CreateBuilder()
{
return CreateBuilder(config: null);
}
public HttpMessageHandler CreateHandler() public HttpMessageHandler CreateHandler()
{ {
var pathBase = BaseAddress == null ? PathString.Empty : PathString.FromUriComponent(BaseAddress); var pathBase = BaseAddress == null ? PathString.Empty : PathString.FromUriComponent(BaseAddress);
@ -141,8 +76,8 @@ namespace Microsoft.AspNet.TestHost
private class ApplicationWrapper<TContext> : IHttpApplication<TContext> private class ApplicationWrapper<TContext> : IHttpApplication<TContext>
{ {
IHttpApplication<TContext> _application; private readonly IHttpApplication<TContext> _application;
Action _preProcessRequestAsync; private readonly Action _preProcessRequestAsync;
public ApplicationWrapper(IHttpApplication<TContext> application, Action preProcessRequestAsync) public ApplicationWrapper(IHttpApplication<TContext> application, Action preProcessRequestAsync)
{ {

View File

@ -4,7 +4,6 @@
using System; using System;
using System.IO; using System.IO;
using Microsoft.AspNet.FileProviders; using Microsoft.AspNet.FileProviders;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Hosting.Internal; using Microsoft.AspNet.Hosting.Internal;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Xunit; using Xunit;
@ -18,7 +17,7 @@ namespace Microsoft.AspNet.Hosting.Tests
{ {
var env = new HostingEnvironment(); var env = new HostingEnvironment();
env.Initialize(".", new WebHostOptions() {WebRoot = "testroot"}, null); env.Initialize(".", new WebApplicationOptions() {WebRoot = "testroot"}, null);
Assert.Equal(Path.GetFullPath("testroot"), env.WebRootPath); Assert.Equal(Path.GetFullPath("testroot"), env.WebRootPath);
Assert.IsAssignableFrom<PhysicalFileProvider>(env.WebRootFileProvider); Assert.IsAssignableFrom<PhysicalFileProvider>(env.WebRootFileProvider);
@ -29,7 +28,7 @@ namespace Microsoft.AspNet.Hosting.Tests
{ {
var env = new HostingEnvironment(); var env = new HostingEnvironment();
env.Initialize("testroot", new WebHostOptions(), null); env.Initialize("testroot", new WebApplicationOptions(), null);
Assert.Equal(Path.GetFullPath(Path.Combine("testroot","wwwroot")), env.WebRootPath); Assert.Equal(Path.GetFullPath(Path.Combine("testroot","wwwroot")), env.WebRootPath);
Assert.IsAssignableFrom<PhysicalFileProvider>(env.WebRootFileProvider); Assert.IsAssignableFrom<PhysicalFileProvider>(env.WebRootFileProvider);
@ -40,7 +39,7 @@ namespace Microsoft.AspNet.Hosting.Tests
{ {
var env = new HostingEnvironment(); var env = new HostingEnvironment();
env.Initialize(Path.Combine("testroot", "wwwroot"), new WebHostOptions(), null); env.Initialize(Path.Combine("testroot", "wwwroot"), new WebApplicationOptions(), null);
Assert.Null(env.WebRootPath); Assert.Null(env.WebRootPath);
Assert.IsAssignableFrom<NullFileProvider>(env.WebRootFileProvider); Assert.IsAssignableFrom<NullFileProvider>(env.WebRootFileProvider);
@ -52,7 +51,7 @@ namespace Microsoft.AspNet.Hosting.Tests
var config = new ConfigurationBuilder().Build(); var config = new ConfigurationBuilder().Build();
var env = new HostingEnvironment(); var env = new HostingEnvironment();
env.Initialize(".", new WebHostOptions(), config); env.Initialize(".", new WebApplicationOptions(), config);
Assert.Same(config, env.Configuration); Assert.Same(config, env.Configuration);
} }
@ -63,7 +62,7 @@ namespace Microsoft.AspNet.Hosting.Tests
var env = new HostingEnvironment(); var env = new HostingEnvironment();
env.EnvironmentName = "SomeName"; env.EnvironmentName = "SomeName";
env.Initialize(".", new WebHostOptions() { Environment = "NewName" }, null); env.Initialize(".", new WebApplicationOptions() { Environment = "NewName" }, null);
Assert.Equal("NewName", env.EnvironmentName); Assert.Equal("NewName", env.EnvironmentName);
} }
@ -73,7 +72,7 @@ namespace Microsoft.AspNet.Hosting.Tests
{ {
var env = new HostingEnvironment(); var env = new HostingEnvironment();
env.Initialize(".", new WebHostOptions(), null); env.Initialize(".", new WebApplicationOptions(), null);
Assert.Throws<InvalidOperationException>(() => env.MapPath("file.txt")); Assert.Throws<InvalidOperationException>(() => env.MapPath("file.txt"));
} }

View File

@ -7,6 +7,7 @@ using System.Reflection;
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Builder.Internal; using Microsoft.AspNet.Builder.Internal;
using Microsoft.AspNet.Hosting.Fakes; using Microsoft.AspNet.Hosting.Fakes;
using Microsoft.AspNet.Hosting.Internal;
using Microsoft.AspNet.Hosting.Startup; using Microsoft.AspNet.Hosting.Startup;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.OptionsModel; using Microsoft.Extensions.OptionsModel;

View File

@ -17,35 +17,25 @@ using Xunit;
namespace Microsoft.AspNet.Hosting namespace Microsoft.AspNet.Hosting
{ {
public class WebHostBuilderTests public class WebApplicationBuilderTests
{ {
[Fact]
public void Build_uses_application_for_startup_assembly_by_default()
{
var builder = CreateWebHostBuilder();
var engine = (HostingEngine)builder.Build();
Assert.Equal("Microsoft.AspNet.Hosting.Tests", engine.StartupAssemblyName);
}
[Fact] [Fact]
public void Build_honors_UseStartup_with_string() public void Build_honors_UseStartup_with_string()
{ {
var builder = CreateWebHostBuilder(); var builder = CreateWebApplicationBuilder().UseServer(new TestServer());
var engine = (HostingEngine)builder.UseStartup("MyStartupAssembly").Build(); var application = (WebApplication)builder.UseStartup("MyStartupAssembly").Build();
Assert.Equal("MyStartupAssembly", engine.StartupAssemblyName); Assert.Equal("MyStartupAssembly", application.StartupAssemblyName);
} }
[Fact] [Fact]
public async Task StartupMissing_Fallback() public async Task StartupMissing_Fallback()
{ {
var builder = CreateWebHostBuilder(); var builder = CreateWebApplicationBuilder();
var server = new TestServer(); var server = new TestServer();
var engine = builder.UseServer(server).UseStartup("MissingStartupAssembly").Build(); var application = builder.UseServer(server).UseStartup("MissingStartupAssembly").Build();
using (engine.Start()) using (application.Start())
{ {
await AssertResponseContains(server.RequestDelegate, "MissingStartupAssembly"); await AssertResponseContains(server.RequestDelegate, "MissingStartupAssembly");
} }
@ -54,10 +44,10 @@ namespace Microsoft.AspNet.Hosting
[Fact] [Fact]
public async Task StartupStaticCtorThrows_Fallback() public async Task StartupStaticCtorThrows_Fallback()
{ {
var builder = CreateWebHostBuilder(); var builder = CreateWebApplicationBuilder();
var server = new TestServer(); var server = new TestServer();
var engine = builder.UseServer(server).UseStartup<StartupStaticCtorThrows>().Build(); var application = builder.UseServer(server).UseStartup<StartupStaticCtorThrows>().Build();
using (engine.Start()) using (application.Start())
{ {
await AssertResponseContains(server.RequestDelegate, "Exception from static constructor"); await AssertResponseContains(server.RequestDelegate, "Exception from static constructor");
} }
@ -66,10 +56,10 @@ namespace Microsoft.AspNet.Hosting
[Fact] [Fact]
public async Task StartupCtorThrows_Fallback() public async Task StartupCtorThrows_Fallback()
{ {
var builder = CreateWebHostBuilder(); var builder = CreateWebApplicationBuilder();
var server = new TestServer(); var server = new TestServer();
var engine = builder.UseServer(server).UseStartup<StartupCtorThrows>().Build(); var application = builder.UseServer(server).UseStartup<StartupCtorThrows>().Build();
using (engine.Start()) using (application.Start())
{ {
await AssertResponseContains(server.RequestDelegate, "Exception from constructor"); await AssertResponseContains(server.RequestDelegate, "Exception from constructor");
} }
@ -78,10 +68,10 @@ namespace Microsoft.AspNet.Hosting
[Fact] [Fact]
public async Task StartupCtorThrows_TypeLoadException() public async Task StartupCtorThrows_TypeLoadException()
{ {
var builder = CreateWebHostBuilder(); var builder = CreateWebApplicationBuilder();
var server = new TestServer(); var server = new TestServer();
var engine = builder.UseServer(server).UseStartup<StartupThrowTypeLoadException>().Build(); var application = builder.UseServer(server).UseStartup<StartupThrowTypeLoadException>().Build();
using (engine.Start()) using (application.Start())
{ {
await AssertResponseContains(server.RequestDelegate, "Message from the LoaderException</span>"); await AssertResponseContains(server.RequestDelegate, "Message from the LoaderException</span>");
} }
@ -90,12 +80,12 @@ namespace Microsoft.AspNet.Hosting
[Fact] [Fact]
public async Task IApplicationLifetimeRegisteredEvenWhenStartupCtorThrows_Fallback() public async Task IApplicationLifetimeRegisteredEvenWhenStartupCtorThrows_Fallback()
{ {
var builder = CreateWebHostBuilder(); var builder = CreateWebApplicationBuilder();
var server = new TestServer(); var server = new TestServer();
var engine = builder.UseServer(server).UseStartup<StartupCtorThrows>().Build(); var application = builder.UseServer(server).UseStartup<StartupCtorThrows>().Build();
using (engine.Start()) using (application.Start())
{ {
var service = engine.ApplicationServices.GetServices<IApplicationLifetime>(); var service = application.Services.GetServices<IApplicationLifetime>();
Assert.NotNull(service); Assert.NotNull(service);
await AssertResponseContains(server.RequestDelegate, "Exception from constructor"); await AssertResponseContains(server.RequestDelegate, "Exception from constructor");
} }
@ -104,10 +94,10 @@ namespace Microsoft.AspNet.Hosting
[Fact] [Fact]
public async Task StartupConfigureServicesThrows_Fallback() public async Task StartupConfigureServicesThrows_Fallback()
{ {
var builder = CreateWebHostBuilder(); var builder = CreateWebApplicationBuilder();
var server = new TestServer(); var server = new TestServer();
var engine = builder.UseServer(server).UseStartup<StartupConfigureServicesThrows>().Build(); var application = builder.UseServer(server).UseStartup<StartupConfigureServicesThrows>().Build();
using (engine.Start()) using (application.Start())
{ {
await AssertResponseContains(server.RequestDelegate, "Exception from ConfigureServices"); await AssertResponseContains(server.RequestDelegate, "Exception from ConfigureServices");
} }
@ -116,10 +106,10 @@ namespace Microsoft.AspNet.Hosting
[Fact] [Fact]
public async Task StartupConfigureThrows_Fallback() public async Task StartupConfigureThrows_Fallback()
{ {
var builder = CreateWebHostBuilder(); var builder = CreateWebApplicationBuilder();
var server = new TestServer(); var server = new TestServer();
var engine = builder.UseServer(server).UseStartup<StartupConfigureServicesThrows>().Build(); var application = builder.UseServer(server).UseStartup<StartupConfigureServicesThrows>().Build();
using (engine.Start()) using (application.Start())
{ {
await AssertResponseContains(server.RequestDelegate, "Exception from Configure"); await AssertResponseContains(server.RequestDelegate, "Exception from Configure");
} }
@ -137,22 +127,27 @@ namespace Microsoft.AspNet.Hosting
var config = builder.Build(); var config = builder.Build();
var expected = "MY_TEST_ENVIRONMENT"; var expected = "MY_TEST_ENVIRONMENT";
var webHost = new WebHostBuilder(config, captureStartupErrors: true).UseEnvironment(expected).Build(); var application = new WebApplicationBuilder()
.UseConfiguration(config)
.UseEnvironment(expected)
.UseServer(new TestServer())
.UseStartup("Microsoft.AspNet.Hosting.Tests")
.Build();
Assert.Equal(expected, webHost.ApplicationServices.GetService<IHostingEnvironment>().EnvironmentName); Assert.Equal(expected, application.Services.GetService<IHostingEnvironment>().EnvironmentName);
} }
private WebHostBuilder CreateWebHostBuilder() private WebApplicationBuilder CreateWebApplicationBuilder()
{ {
var vals = new Dictionary<string, string> var vals = new Dictionary<string, string>
{ {
{ "server", "Microsoft.AspNet.Hosting.Tests" },
{ "DetailedErrors", "true" }, { "DetailedErrors", "true" },
{ "captureStartupErrors", "true" }
}; };
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.AddInMemoryCollection(vals); .AddInMemoryCollection(vals);
var config = builder.Build(); var config = builder.Build();
return new WebHostBuilder(config, captureStartupErrors: true); return new WebApplicationBuilder().UseConfiguration(config);
} }
private async Task AssertResponseContains(RequestDelegate app, string expectedText) private async Task AssertResponseContains(RequestDelegate app, string expectedText)

View File

@ -1,23 +1,14 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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.Collections.Generic;
using System.IO; using Microsoft.AspNet.Hosting.Internal;
using System.Reflection;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Builder.Internal;
using Microsoft.AspNet.Hosting.Fakes;
using Microsoft.AspNet.Hosting.Startup;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.OptionsModel;
using Xunit; using Xunit;
namespace Microsoft.AspNet.Hosting.Tests namespace Microsoft.AspNet.Hosting.Tests
{ {
public class WebHostConfigurationTests public class WebApplicationConfigurationTests
{ {
[Fact] [Fact]
public void ReadsParametersCorrectly() public void ReadsParametersCorrectly()
@ -29,22 +20,24 @@ namespace Microsoft.AspNet.Hosting.Tests
{"app", "MyProjectReference"}, {"app", "MyProjectReference"},
{"environment", "Development"}, {"environment", "Development"},
{"detailederrors", "true"}, {"detailederrors", "true"},
{ "captureStartupErrors", "true" }
}; };
var config = new WebHostOptions(new ConfigurationBuilder().AddInMemoryCollection(parameters).Build()); var config = new WebApplicationOptions(new ConfigurationBuilder().AddInMemoryCollection(parameters).Build());
Assert.Equal("wwwroot", config.WebRoot); Assert.Equal("wwwroot", config.WebRoot);
Assert.Equal("Microsoft.AspNet.Server.Kestrel", config.Server); Assert.Equal("Microsoft.AspNet.Server.Kestrel", config.ServerFactoryLocation);
Assert.Equal("MyProjectReference", config.Application); Assert.Equal("MyProjectReference", config.Application);
Assert.Equal("Development", config.Environment); Assert.Equal("Development", config.Environment);
Assert.Equal(true, config.DetailedErrors); Assert.True(config.CaptureStartupErrors);
Assert.True(config.DetailedErrors);
} }
[Fact] [Fact]
public void ReadsOldEnvKey() public void ReadsOldEnvKey()
{ {
var parameters = new Dictionary<string, string>() { { "ENV", "Development" } }; var parameters = new Dictionary<string, string>() { { "ENV", "Development" } };
var config = new WebHostOptions(new ConfigurationBuilder().AddInMemoryCollection(parameters).Build()); var config = new WebApplicationOptions(new ConfigurationBuilder().AddInMemoryCollection(parameters).Build());
Assert.Equal("Development", config.Environment); Assert.Equal("Development", config.Environment);
} }
@ -55,7 +48,7 @@ namespace Microsoft.AspNet.Hosting.Tests
public void AllowsNumberForDetailedErrors(string value, bool expected) public void AllowsNumberForDetailedErrors(string value, bool expected)
{ {
var parameters = new Dictionary<string, string>() { { "detailedErrors", value } }; var parameters = new Dictionary<string, string>() { { "detailedErrors", value } };
var config = new WebHostOptions(new ConfigurationBuilder().AddInMemoryCollection(parameters).Build()); var config = new WebApplicationOptions(new ConfigurationBuilder().AddInMemoryCollection(parameters).Build());
Assert.Equal(expected, config.DetailedErrors); Assert.Equal(expected, config.DetailedErrors);
} }

View File

@ -9,7 +9,6 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting.Fakes; using Microsoft.AspNet.Hosting.Fakes;
using Microsoft.AspNet.Hosting.Internal;
using Microsoft.AspNet.Hosting.Server; using Microsoft.AspNet.Hosting.Server;
using Microsoft.AspNet.Hosting.Startup; using Microsoft.AspNet.Hosting.Startup;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
@ -25,7 +24,7 @@ using Xunit;
namespace Microsoft.AspNet.Hosting namespace Microsoft.AspNet.Hosting
{ {
public class HostingEngineTests : IServerFactory, IServer public class WebApplicationTests : IServerFactory, IServer
{ {
private readonly IList<StartInstance> _startInstances = new List<StartInstance>(); private readonly IList<StartInstance> _startInstances = new List<StartInstance>();
private IFeatureCollection _featuresSupportedByThisHost = NewFeatureCollection(); private IFeatureCollection _featuresSupportedByThisHost = NewFeatureCollection();
@ -63,7 +62,7 @@ namespace Microsoft.AspNet.Hosting
} }
[Fact] [Fact]
public void HostingEngineThrowsWithNoServer() public void WebApplicationThrowsWithNoServer()
{ {
var ex = Assert.Throws<InvalidOperationException>(() => CreateBuilder().Build().Start()); var ex = Assert.Throws<InvalidOperationException>(() => CreateBuilder().Build().Start());
Assert.True(ex.Message.Contains("UseServer()")); Assert.True(ex.Message.Contains("UseServer()"));
@ -86,9 +85,9 @@ namespace Microsoft.AspNet.Hosting
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.AddInMemoryCollection(vals); .AddInMemoryCollection(vals);
var config = builder.Build(); var config = builder.Build();
var host = CreateBuilder(config).Build(); var application = CreateBuilder(config).Build();
host.Start(); application.Start();
Assert.NotNull(host.ApplicationServices.GetRequiredService<IHostingEnvironment>()); Assert.NotNull(application.Services.GetService<IHostingEnvironment>());
} }
[Fact] [Fact]
@ -102,9 +101,9 @@ namespace Microsoft.AspNet.Hosting
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.AddInMemoryCollection(vals); .AddInMemoryCollection(vals);
var config = builder.Build(); var config = builder.Build();
var host = CreateBuilder(config).Build(); var application = CreateBuilder(config).Build();
host.Start(); application.Start();
Assert.NotNull(host.ApplicationServices.GetRequiredService<IHostingEnvironment>()); Assert.NotNull(application.Services.GetService<IHostingEnvironment>());
} }
[Fact] [Fact]
@ -119,10 +118,10 @@ namespace Microsoft.AspNet.Hosting
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.AddInMemoryCollection(vals); .AddInMemoryCollection(vals);
var config = builder.Build(); var config = builder.Build();
var host = CreateBuilder(config).Build(); var application = CreateBuilder(config).Build();
var app = host.Start(); var app = application.Start();
Assert.NotNull(host.ApplicationServices.GetRequiredService<IHostingEnvironment>()); Assert.NotNull(application.Services.GetService<IHostingEnvironment>());
Assert.Equal("http://localhost:abc123", app.ServerFeatures.Get<IServerAddressesFeature>().Addresses.First()); Assert.Equal("http://localhost:abc123", application.ServerFeatures.Get<IServerAddressesFeature>().Addresses.First());
} }
[Fact] [Fact]
@ -136,10 +135,10 @@ namespace Microsoft.AspNet.Hosting
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.AddInMemoryCollection(vals); .AddInMemoryCollection(vals);
var config = builder.Build(); var config = builder.Build();
var host = CreateBuilder(config).Build(); var application = CreateBuilder(config).Build();
var app = host.Start(); var app = application.Start();
Assert.NotNull(host.ApplicationServices.GetRequiredService<IHostingEnvironment>()); Assert.NotNull(application.Services.GetService<IHostingEnvironment>());
Assert.Equal("http://localhost:5000", app.ServerFeatures.Get<IServerAddressesFeature>().Addresses.First()); Assert.Equal("http://localhost:5000", application.GetAddresses().First());
} }
[Fact] [Fact]
@ -153,84 +152,85 @@ namespace Microsoft.AspNet.Hosting
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.AddInMemoryCollection(vals); .AddInMemoryCollection(vals);
var config = builder.Build(); var config = builder.Build();
var host = CreateBuilder(config).Build(); var application = CreateBuilder(config).Build();
var app = host.Start(); var app = application.Start();
var hostingEnvironment = host.ApplicationServices.GetRequiredService<IHostingEnvironment>(); var hostingEnvironment = application.Services.GetService<IHostingEnvironment>();
Assert.NotNull(hostingEnvironment.Configuration); Assert.NotNull(hostingEnvironment.Configuration);
Assert.Equal("Microsoft.AspNet.Hosting.Tests", hostingEnvironment.Configuration["Server"]); Assert.Equal("Microsoft.AspNet.Hosting.Tests", hostingEnvironment.Configuration["Server"]);
} }
[Fact] [Fact]
public void HostingEngineCanBeStarted() public void WebApplicationCanBeStarted()
{ {
var engine = CreateBuilder() var app = CreateBuilder()
.UseServer(this) .UseServer(this)
.UseStartup("Microsoft.AspNet.Hosting.Tests") .UseStartup("Microsoft.AspNet.Hosting.Tests")
.Build() .Build()
.Start(); .Start();
Assert.NotNull(engine); Assert.NotNull(app);
Assert.Equal(1, _startInstances.Count); Assert.Equal(1, _startInstances.Count);
Assert.Equal(0, _startInstances[0].DisposeCalls); Assert.Equal(0, _startInstances[0].DisposeCalls);
engine.Dispose(); app.Dispose();
Assert.Equal(1, _startInstances[0].DisposeCalls); Assert.Equal(1, _startInstances[0].DisposeCalls);
} }
[Fact] [Fact]
public void HostingEngineDisposesServiceProvider() public void WebApplicationDisposesServiceProvider()
{ {
var engine = CreateBuilder() var application = CreateBuilder()
.UseServer(this) .UseServer(this)
.UseServices(s => .ConfigureServices(s =>
{ {
s.AddTransient<IFakeService, FakeService>(); s.AddTransient<IFakeService, FakeService>();
s.AddSingleton<IFakeSingletonService, FakeService>(); s.AddSingleton<IFakeSingletonService, FakeService>();
}) })
.UseStartup("Microsoft.AspNet.Hosting.Tests") .UseStartup("Microsoft.AspNet.Hosting.Tests")
.Build() .Build();
.Start();
var singleton = (FakeService)engine.Services.GetService<IFakeSingletonService>(); var app = application.Start();
var transient = (FakeService)engine.Services.GetService<IFakeService>();
var singleton = (FakeService)application.Services.GetService<IFakeSingletonService>();
var transient = (FakeService)application.Services.GetService<IFakeService>();
Assert.False(singleton.Disposed); Assert.False(singleton.Disposed);
Assert.False(transient.Disposed); Assert.False(transient.Disposed);
engine.Dispose(); app.Dispose();
Assert.True(singleton.Disposed); Assert.True(singleton.Disposed);
Assert.True(transient.Disposed); Assert.True(transient.Disposed);
} }
[Fact] [Fact]
public void HostingEngineNotifiesApplicationStarted() public void WebApplicationNotifiesApplicationStarted()
{ {
var host = CreateBuilder() var application = CreateBuilder()
.UseServer(this) .UseServer(this)
.Build(); .Build();
var applicationLifetime = host.ApplicationServices.GetRequiredService<IApplicationLifetime>(); var applicationLifetime = application.Services.GetService<IApplicationLifetime>();
Assert.False(applicationLifetime.ApplicationStarted.IsCancellationRequested); Assert.False(applicationLifetime.ApplicationStarted.IsCancellationRequested);
using (host.Start()) using (application.Start())
{ {
Assert.True(applicationLifetime.ApplicationStarted.IsCancellationRequested); Assert.True(applicationLifetime.ApplicationStarted.IsCancellationRequested);
} }
} }
[Fact] [Fact]
public void HostingEngineInjectsHostingEnvironment() public void WebApplicationInjectsHostingEnvironment()
{ {
var engine = CreateBuilder() var application = CreateBuilder()
.UseServer(this) .UseServer(this)
.UseStartup("Microsoft.AspNet.Hosting.Tests") .UseStartup("Microsoft.AspNet.Hosting.Tests")
.UseEnvironment("WithHostingEnvironment") .UseEnvironment("WithHostingEnvironment")
.Build(); .Build();
using (var server = engine.Start()) using (application.Start())
{ {
var env = engine.ApplicationServices.GetRequiredService<IHostingEnvironment>(); var env = application.Services.GetService<IHostingEnvironment>();
Assert.Equal("Changed", env.EnvironmentName); Assert.Equal("Changed", env.EnvironmentName);
} }
} }
@ -238,26 +238,29 @@ namespace Microsoft.AspNet.Hosting
[Fact] [Fact]
public void CanReplaceStartupLoader() public void CanReplaceStartupLoader()
{ {
var engine = CreateBuilder().UseServices(services => services.AddTransient<IStartupLoader, TestLoader>()) var builder = CreateBuilder()
.ConfigureServices(services =>
{
services.AddTransient<IStartupLoader, TestLoader>();
})
.UseServer(this) .UseServer(this)
.UseStartup("Microsoft.AspNet.Hosting.Tests") .UseStartup("Microsoft.AspNet.Hosting.Tests");
.Build();
Assert.Throws<NotImplementedException>(() => engine.Start()); Assert.Throws<NotImplementedException>(() => builder.Build());
} }
[Fact] [Fact]
public void CanCreateApplicationServicesWithAddedServices() public void CanCreateApplicationServicesWithAddedServices()
{ {
var host = CreateBuilder().UseServices(services => services.AddOptions()).Build(); var application = CreateBuilder().UseServer(this).ConfigureServices(services => services.AddOptions()).Build();
Assert.NotNull(host.ApplicationServices.GetRequiredService<IOptions<object>>()); Assert.NotNull(application.Services.GetRequiredService<IOptions<object>>());
} }
[Fact] [Fact]
public void EnvDefaultsToProductionIfNoConfig() public void EnvDefaultsToProductionIfNoConfig()
{ {
var engine = CreateBuilder().Build(); var application = CreateBuilder().UseServer(this).Build();
var env = engine.ApplicationServices.GetRequiredService<IHostingEnvironment>(); var env = application.Services.GetService<IHostingEnvironment>();
Assert.Equal(EnvironmentName.Production, env.EnvironmentName); Assert.Equal(EnvironmentName.Production, env.EnvironmentName);
} }
@ -266,7 +269,7 @@ namespace Microsoft.AspNet.Hosting
{ {
var vals = new Dictionary<string, string> var vals = new Dictionary<string, string>
{ {
// Old key is actualy ASPNET_ENV but WebHostConfiguration expects environment // Old key is actualy ASPNET_ENV but WebApplicationConfiguration expects environment
// variable names stripped from ASPNET_ prefix so using just ENV here // variable names stripped from ASPNET_ prefix so using just ENV here
{ "ENV", "Staging" } { "ENV", "Staging" }
}; };
@ -275,8 +278,8 @@ namespace Microsoft.AspNet.Hosting
.AddInMemoryCollection(vals); .AddInMemoryCollection(vals);
var config = builder.Build(); var config = builder.Build();
var engine = CreateBuilder(config).Build(); var application = CreateBuilder(config).UseServer(this).Build();
var env = engine.ApplicationServices.GetRequiredService<IHostingEnvironment>(); var env = application.Services.GetService<IHostingEnvironment>();
Assert.Equal("Staging", env.EnvironmentName); Assert.Equal("Staging", env.EnvironmentName);
} }
@ -292,8 +295,8 @@ namespace Microsoft.AspNet.Hosting
.AddInMemoryCollection(vals); .AddInMemoryCollection(vals);
var config = builder.Build(); var config = builder.Build();
var engine = CreateBuilder(config).Build(); var application = CreateBuilder(config).UseServer(this).Build();
var env = engine.ApplicationServices.GetRequiredService<IHostingEnvironment>(); var env = application.Services.GetService<IHostingEnvironment>();
Assert.Equal("Staging", env.EnvironmentName); Assert.Equal("Staging", env.EnvironmentName);
} }
@ -309,8 +312,8 @@ namespace Microsoft.AspNet.Hosting
.AddInMemoryCollection(vals); .AddInMemoryCollection(vals);
var config = builder.Build(); var config = builder.Build();
var engine = CreateBuilder(config).UseServer(this).Build(); var application = CreateBuilder(config).UseServer(this).Build();
var env = engine.ApplicationServices.GetRequiredService<IHostingEnvironment>(); var env = application.Services.GetService<IHostingEnvironment>();
Assert.Equal(Path.GetFullPath("testroot"), env.WebRootPath); Assert.Equal(Path.GetFullPath("testroot"), env.WebRootPath);
Assert.True(env.WebRootFileProvider.GetFileInfo("TextFile.txt").Exists); Assert.True(env.WebRootFileProvider.GetFileInfo("TextFile.txt").Exists);
} }
@ -318,10 +321,10 @@ namespace Microsoft.AspNet.Hosting
[Fact] [Fact]
public void IsEnvironment_Extension_Is_Case_Insensitive() public void IsEnvironment_Extension_Is_Case_Insensitive()
{ {
var engine = CreateBuilder().UseServer(this).Build(); var application = CreateBuilder().UseServer(this).Build();
using (engine.Start()) using (application.Start())
{ {
var env = engine.ApplicationServices.GetRequiredService<IHostingEnvironment>(); var env = application.Services.GetRequiredService<IHostingEnvironment>();
Assert.True(env.IsEnvironment(EnvironmentName.Production)); Assert.True(env.IsEnvironment(EnvironmentName.Production));
Assert.True(env.IsEnvironment("producTion")); Assert.True(env.IsEnvironment("producTion"));
} }
@ -349,7 +352,7 @@ namespace Microsoft.AspNet.Hosting
} }
[Fact] [Fact]
public void HostingEngine_CreatesDefaultRequestIdentifierFeature_IfNotPresent() public void WebApplication_CreatesDefaultRequestIdentifierFeature_IfNotPresent()
{ {
// Arrange // Arrange
HttpContext httpContext = null; HttpContext httpContext = null;
@ -358,10 +361,10 @@ namespace Microsoft.AspNet.Hosting
httpContext = innerHttpContext; httpContext = innerHttpContext;
return Task.FromResult(0); return Task.FromResult(0);
}); });
var hostingEngine = CreateHostingEngine(requestDelegate); var application = CreateApplication(requestDelegate);
// Act // Act
var disposable = hostingEngine.Start(); var disposable = application.Start();
// Assert // Assert
Assert.NotNull(httpContext); Assert.NotNull(httpContext);
@ -371,7 +374,7 @@ namespace Microsoft.AspNet.Hosting
} }
[Fact] [Fact]
public void HostingEngine_DoesNot_CreateDefaultRequestIdentifierFeature_IfPresent() public void WebApplication_DoesNot_CreateDefaultRequestIdentifierFeature_IfPresent()
{ {
// Arrange // Arrange
HttpContext httpContext = null; HttpContext httpContext = null;
@ -382,10 +385,10 @@ namespace Microsoft.AspNet.Hosting
}); });
var requestIdentifierFeature = new StubHttpRequestIdentifierFeature(); var requestIdentifierFeature = new StubHttpRequestIdentifierFeature();
_featuresSupportedByThisHost[typeof(IHttpRequestIdentifierFeature)] = requestIdentifierFeature; _featuresSupportedByThisHost[typeof(IHttpRequestIdentifierFeature)] = requestIdentifierFeature;
var hostingEngine = CreateHostingEngine(requestDelegate); var application = CreateApplication(requestDelegate);
// Act // Act
var disposable = hostingEngine.Start(); var disposable = application.Start();
// Assert // Assert
Assert.NotNull(httpContext); Assert.NotNull(httpContext);
@ -393,16 +396,16 @@ namespace Microsoft.AspNet.Hosting
} }
[Fact] [Fact]
public void HostingEngine_InvokesConfigureMethodsOnlyOnce() public void WebApplication_InvokesConfigureMethodsOnlyOnce()
{ {
var engine = CreateBuilder() var application = CreateBuilder()
.UseServer(this) .UseServer(this)
.UseStartup<CountStartup>() .UseStartup<CountStartup>()
.Build(); .Build();
using (engine.Start()) using (application.Start())
{ {
var services = engine.ApplicationServices; var services = application.Services;
var services2 = engine.ApplicationServices; var services2 = application.Services;
Assert.Equal(1, CountStartup.ConfigureCount); Assert.Equal(1, CountStartup.ConfigureCount);
Assert.Equal(1, CountStartup.ConfigureServicesCount); Assert.Equal(1, CountStartup.ConfigureServicesCount);
} }
@ -425,13 +428,13 @@ namespace Microsoft.AspNet.Hosting
} }
[Fact] [Fact]
public void HostingEngine_ThrowsForBadConfigureServiceSignature() public void WebApplication_ThrowsForBadConfigureServiceSignature()
{ {
var engine = CreateBuilder() var builder = CreateBuilder()
.UseServer(this) .UseServer(this)
.UseStartup<BadConfigureServicesStartup>() .UseStartup<BadConfigureServicesStartup>();
.Build();
var ex = Assert.Throws<InvalidOperationException>(() => engine.Start()); var ex = Assert.Throws<InvalidOperationException>(() => builder.Build());
Assert.True(ex.Message.Contains("ConfigureServices")); Assert.True(ex.Message.Contains("ConfigureServices"));
} }
@ -441,27 +444,26 @@ namespace Microsoft.AspNet.Hosting
public void Configure(IApplicationBuilder app) { } public void Configure(IApplicationBuilder app) { }
} }
private IHostingEngine CreateHostingEngine(RequestDelegate requestDelegate) private IWebApplication CreateApplication(RequestDelegate requestDelegate)
{ {
var host = CreateBuilder() var builder = CreateBuilder()
.UseServer(this) .UseServer(this)
.UseStartup( .Configure(
appBuilder => appBuilder =>
{ {
appBuilder.ApplicationServices.GetRequiredService<ILoggerFactory>().AddProvider(new AllMessagesAreNeeded()); appBuilder.ApplicationServices.GetRequiredService<ILoggerFactory>().AddProvider(new AllMessagesAreNeeded());
appBuilder.Run(requestDelegate); appBuilder.Run(requestDelegate);
}, });
configureServices => configureServices.BuildServiceProvider()); return builder.Build();
return host.Build();
} }
private void RunMapPath(string virtualPath, string expectedSuffix) private void RunMapPath(string virtualPath, string expectedSuffix)
{ {
var engine = CreateBuilder().UseServer(this).Build(); var application = CreateBuilder().UseServer(this).Build();
using (engine.Start()) using (application.Start())
{ {
var env = engine.ApplicationServices.GetRequiredService<IHostingEnvironment>(); var env = application.Services.GetRequiredService<IHostingEnvironment>();
// MapPath requires webroot to be set, we don't care // MapPath requires webroot to be set, we don't care
// about file provider so just set it here // about file provider so just set it here
env.WebRootPath = "."; env.WebRootPath = ".";
@ -471,9 +473,9 @@ namespace Microsoft.AspNet.Hosting
} }
} }
private WebHostBuilder CreateBuilder(IConfiguration config = null) private WebApplicationBuilder CreateBuilder(IConfiguration config = null)
{ {
return new WebHostBuilder(config ?? new ConfigurationBuilder().Build()); return new WebApplicationBuilder().UseConfiguration(config ?? new ConfigurationBuilder().Build()).UseStartup("Microsoft.AspNet.Hosting.Tests");
} }
public void Start<TContext>(IHttpApplication<TContext> application) public void Start<TContext>(IHttpApplication<TContext> application)

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Testing.xunit; using Microsoft.AspNet.Testing.xunit;
using Xunit; using Xunit;
@ -13,7 +14,8 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono)] [FrameworkSkipCondition(RuntimeFrameworks.Mono)]
public void AddRequestHeader() public void AddRequestHeader()
{ {
var server = TestServer.Create(app => { }); var builder = new WebApplicationBuilder().Configure(app => { });
var server = new TestServer(builder);
server.CreateRequest("/") server.CreateRequest("/")
.AddHeader("Host", "MyHost:90") .AddHeader("Host", "MyHost:90")
.And(request => .And(request =>
@ -25,7 +27,8 @@ namespace Microsoft.AspNet.TestHost
[Fact] [Fact]
public void AddContentHeaders() public void AddContentHeaders()
{ {
var server = TestServer.Create(app => { }); var builder = new WebApplicationBuilder().Configure(app => { });
var server = new TestServer(builder);
server.CreateRequest("/") server.CreateRequest("/")
.AddHeader("Content-Type", "Test/Value") .AddHeader("Content-Type", "Test/Value")
.And(request => .And(request =>

View File

@ -10,6 +10,7 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Testing.xunit; using Microsoft.AspNet.Testing.xunit;
using Xunit; using Xunit;
@ -22,7 +23,7 @@ namespace Microsoft.AspNet.TestHost
public TestClientTests() public TestClientTests()
{ {
_server = TestServer.Create(app => app.Run(ctx => Task.FromResult(0))); _server = new TestServer(new WebApplicationBuilder().Configure(app => app.Run(ctx => Task.FromResult(0))));
} }
[ConditionalFact] [ConditionalFact]
@ -33,7 +34,8 @@ namespace Microsoft.AspNet.TestHost
var expected = "GET Response"; var expected = "GET Response";
RequestDelegate appDelegate = ctx => RequestDelegate appDelegate = ctx =>
ctx.Response.WriteAsync(expected); ctx.Response.WriteAsync(expected);
var server = TestServer.Create(app => app.Run(appDelegate)); var builder = new WebApplicationBuilder().Configure(app => app.Run(appDelegate));
var server = new TestServer(builder);
var client = server.CreateClient(); var client = server.CreateClient();
// Act // Act
@ -55,7 +57,8 @@ namespace Microsoft.AspNet.TestHost
Assert.Equal("/", ctx.Request.Path.Value); Assert.Equal("/", ctx.Request.Path.Value);
return ctx.Response.WriteAsync(expected); return ctx.Response.WriteAsync(expected);
}; };
var server = TestServer.Create(app => app.Run(appDelegate)); var builder = new WebApplicationBuilder().Configure(app => app.Run(appDelegate));
var server = new TestServer(builder);
var client = server.CreateClient(); var client = server.CreateClient();
// Act // Act
@ -77,7 +80,8 @@ namespace Microsoft.AspNet.TestHost
Assert.Equal("/", ctx.Request.Path.Value); Assert.Equal("/", ctx.Request.Path.Value);
return ctx.Response.WriteAsync(expected); return ctx.Response.WriteAsync(expected);
}; };
var server = TestServer.Create(app => app.Run(appDelegate)); var builder = new WebApplicationBuilder().Configure(app => app.Run(appDelegate));
var server = new TestServer(builder);
var client = server.CreateClient(); var client = server.CreateClient();
// Act // Act
@ -94,7 +98,8 @@ namespace Microsoft.AspNet.TestHost
// Arrange // Arrange
RequestDelegate appDelegate = ctx => RequestDelegate appDelegate = ctx =>
ctx.Response.WriteAsync(new StreamReader(ctx.Request.Body).ReadToEnd() + " PUT Response"); ctx.Response.WriteAsync(new StreamReader(ctx.Request.Body).ReadToEnd() + " PUT Response");
var server = TestServer.Create(app => app.Run(appDelegate)); var builder = new WebApplicationBuilder().Configure(app => app.Run(appDelegate));
var server = new TestServer(builder);
var client = server.CreateClient(); var client = server.CreateClient();
// Act // Act
@ -112,7 +117,8 @@ namespace Microsoft.AspNet.TestHost
// Arrange // Arrange
RequestDelegate appDelegate = async ctx => RequestDelegate appDelegate = async ctx =>
await ctx.Response.WriteAsync(new StreamReader(ctx.Request.Body).ReadToEnd() + " POST Response"); await ctx.Response.WriteAsync(new StreamReader(ctx.Request.Body).ReadToEnd() + " POST Response");
var server = TestServer.Create(app => app.Run(appDelegate)); var builder = new WebApplicationBuilder().Configure(app => app.Run(appDelegate));
var server = new TestServer(builder);
var client = server.CreateClient(); var client = server.CreateClient();
// Act // Act
@ -150,10 +156,11 @@ namespace Microsoft.AspNet.TestHost
} }
} }
}; };
var server = TestServer.Create(app => var builder = new WebApplicationBuilder().Configure(app =>
{ {
app.Run(appDelegate); app.Run(appDelegate);
}); });
var server = new TestServer(builder);
// Act // Act
var client = server.CreateWebSocketClient(); var client = server.CreateWebSocketClient();
@ -198,10 +205,11 @@ namespace Microsoft.AspNet.TestHost
websocket.Dispose(); websocket.Dispose();
} }
}; };
var server = TestServer.Create(app => var builder = new WebApplicationBuilder().Configure(app =>
{ {
app.Run(appDelegate); app.Run(appDelegate);
}); });
var server = new TestServer(builder);
// Act // Act
var client = server.CreateWebSocketClient(); var client = server.CreateWebSocketClient();
@ -231,10 +239,11 @@ namespace Microsoft.AspNet.TestHost
} }
} }
}; };
var server = TestServer.Create(app => var builder = new WebApplicationBuilder().Configure(app =>
{ {
app.Run(appDelegate); app.Run(appDelegate);
}); });
var server = new TestServer(builder);
// Act // Act
var client = server.CreateWebSocketClient(); var client = server.CreateWebSocketClient();
@ -279,7 +288,8 @@ namespace Microsoft.AspNet.TestHost
}; };
// Act // Act
var server = TestServer.Create(app => app.Run(appDelegate)); var builder = new WebApplicationBuilder().Configure(app => app.Run(appDelegate));
var server = new TestServer(builder);
var client = server.CreateClient(); var client = server.CreateClient();
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:12345"); var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:12345");
var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
@ -310,7 +320,8 @@ namespace Microsoft.AspNet.TestHost
}; };
// Act // Act
var server = TestServer.Create(app => app.Run(appDelegate)); var builder = new WebApplicationBuilder().Configure(app => app.Run(appDelegate));
var server = new TestServer(builder);
var client = server.CreateClient(); var client = server.CreateClient();
var cts = new CancellationTokenSource(); var cts = new CancellationTokenSource();
cts.CancelAfter(500); cts.CancelAfter(500);

View File

@ -28,20 +28,21 @@ namespace Microsoft.AspNet.TestHost
{ {
// Arrange // Arrange
// Act & Assert (Does not throw) // Act & Assert (Does not throw)
TestServer.Create(app => { }); new TestServer(new WebApplicationBuilder().Configure(app => { }));
} }
[ConditionalFact] [ConditionalFact]
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task RequestServicesAutoCreated() public async Task RequestServicesAutoCreated()
{ {
var server = TestServer.Create(app => var builder = new WebApplicationBuilder().Configure(app =>
{ {
app.Run(context => app.Run(context =>
{ {
return context.Response.WriteAsync("RequestServices:" + (context.RequestServices != null)); return context.Response.WriteAsync("RequestServices:" + (context.RequestServices != null));
}); });
}); });
var server = new TestServer(builder);
string result = await server.CreateClient().GetStringAsync("/path"); string result = await server.CreateClient().GetStringAsync("/path");
Assert.Equal("RequestServices:True", result); Assert.Equal("RequestServices:True", result);
@ -71,7 +72,8 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task CustomServiceProviderSetsApplicationServices() public async Task CustomServiceProviderSetsApplicationServices()
{ {
var server = new TestServer(TestServer.CreateBuilder().UseStartup<CustomContainerStartup>()); var builder = new WebApplicationBuilder().UseStartup<CustomContainerStartup>();
var server = new TestServer(builder);
string result = await server.CreateClient().GetStringAsync("/path"); string result = await server.CreateClient().GetStringAsync("/path");
Assert.Equal("ApplicationServicesEqual:True", result); Assert.Equal("ApplicationServicesEqual:True", result);
} }
@ -113,15 +115,20 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task ExistingRequestServicesWillNotBeReplaced() public async Task ExistingRequestServicesWillNotBeReplaced()
{ {
var server = TestServer.Create(app => var builder = new WebApplicationBuilder().Configure(app =>
{ {
app.Run(context => app.Run(context =>
{ {
var service = context.RequestServices.GetService<TestService>(); var service = context.RequestServices.GetService<TestService>();
return context.Response.WriteAsync("Found:" + (service != null)); return context.Response.WriteAsync("Found:" + (service != null));
}); });
}, })
services => services.AddTransient<IStartupFilter, RequestServicesFilter>()); .ConfigureServices(services =>
{
services.AddTransient<IStartupFilter, RequestServicesFilter>();
});
var server = new TestServer(builder);
string result = await server.CreateClient().GetStringAsync("/path"); string result = await server.CreateClient().GetStringAsync("/path");
Assert.Equal("Found:True", result); Assert.Equal("Found:True", result);
} }
@ -130,19 +137,21 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task CanSetCustomServiceProvider() public async Task CanSetCustomServiceProvider()
{ {
var server = TestServer.Create(app => var builder = new WebApplicationBuilder().Configure(app =>
{ {
app.Run(context => app.Run(context =>
{ {
context.RequestServices = new ServiceCollection() context.RequestServices = new ServiceCollection()
.AddTransient<TestService>() .AddTransient<TestService>()
.BuildServiceProvider(); .BuildServiceProvider();
var s = context.RequestServices.GetRequiredService<TestService>(); var s = context.RequestServices.GetRequiredService<TestService>();
return context.Response.WriteAsync("Success"); return context.Response.WriteAsync("Success");
}); });
}); });
var server = new TestServer(builder);
string result = await server.CreateClient().GetStringAsync("/path"); string result = await server.CreateClient().GetStringAsync("/path");
Assert.Equal("Success", result); Assert.Equal("Success", result);
} }
@ -178,15 +187,20 @@ namespace Microsoft.AspNet.TestHost
public async Task ExistingServiceProviderFeatureWillNotBeReplaced() public async Task ExistingServiceProviderFeatureWillNotBeReplaced()
{ {
var appServices = new ServiceCollection().BuildServiceProvider(); var appServices = new ServiceCollection().BuildServiceProvider();
var server = TestServer.Create(app => var builder = new WebApplicationBuilder().Configure(app =>
{ {
app.Run(context => app.Run(context =>
{ {
Assert.Equal(appServices, context.RequestServices); Assert.Equal(appServices, context.RequestServices);
return context.Response.WriteAsync("Success"); return context.Response.WriteAsync("Success");
}); });
}, })
services => services.AddSingleton<IStartupFilter>(new ReplaceServiceProvidersFeatureFilter(appServices, appServices))); .ConfigureServices(services =>
{
services.AddSingleton<IStartupFilter>(new ReplaceServiceProvidersFeatureFilter(appServices, appServices));
});
var server = new TestServer(builder);
var result = await server.CreateClient().GetStringAsync("/path"); var result = await server.CreateClient().GetStringAsync("/path");
Assert.Equal("Success", result); Assert.Equal("Success", result);
} }
@ -215,15 +229,20 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task WillReplaceServiceProviderFeatureWithNullRequestServices() public async Task WillReplaceServiceProviderFeatureWithNullRequestServices()
{ {
var server = TestServer.Create(app => var builder = new WebApplicationBuilder().Configure(app =>
{ {
app.Run(context => app.Run(context =>
{ {
Assert.NotNull(context.RequestServices); Assert.NotNull(context.RequestServices);
return context.Response.WriteAsync("Success"); return context.Response.WriteAsync("Success");
}); });
}, })
services => services.AddTransient<IStartupFilter, NullServiceProvidersFeatureFilter>()); .ConfigureServices(services =>
{
services.AddTransient<IStartupFilter, NullServiceProvidersFeatureFilter>();
});
var server = new TestServer(builder);
var result = await server.CreateClient().GetStringAsync("/path"); var result = await server.CreateClient().GetStringAsync("/path");
Assert.Equal("Success", result); Assert.Equal("Success", result);
} }
@ -232,7 +251,7 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task CanAccessLogger() public async Task CanAccessLogger()
{ {
var server = TestServer.Create(app => var builder = new WebApplicationBuilder().Configure(app =>
{ {
app.Run(context => app.Run(context =>
{ {
@ -240,6 +259,7 @@ namespace Microsoft.AspNet.TestHost
return context.Response.WriteAsync("FoundLogger:" + (logger != null)); return context.Response.WriteAsync("FoundLogger:" + (logger != null));
}); });
}); });
var server = new TestServer(builder);
string result = await server.CreateClient().GetStringAsync("/path"); string result = await server.CreateClient().GetStringAsync("/path");
Assert.Equal("FoundLogger:True", result); Assert.Equal("FoundLogger:True", result);
@ -249,18 +269,19 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task CanAccessHttpContext() public async Task CanAccessHttpContext()
{ {
Action<IServiceCollection> configureServices = services => var builder = new WebApplicationBuilder().Configure(app =>
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
};
TestServer server = TestServer.Create(app =>
{ {
app.Run(context => app.Run(context =>
{ {
var accessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>(); var accessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
return context.Response.WriteAsync("HasContext:"+(accessor.HttpContext != null)); return context.Response.WriteAsync("HasContext:" + (accessor.HttpContext != null));
}); });
}, configureServices); })
.ConfigureServices(services =>
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
});
var server = new TestServer(builder);
string result = await server.CreateClient().GetStringAsync("/path"); string result = await server.CreateClient().GetStringAsync("/path");
Assert.Equal("HasContext:True", result); Assert.Equal("HasContext:True", result);
@ -280,19 +301,20 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task CanAddNewHostServices() public async Task CanAddNewHostServices()
{ {
Action<IServiceCollection> configureServices = services => var builder = new WebApplicationBuilder().Configure(app =>
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<ContextHolder>();
};
TestServer server = TestServer.Create(app =>
{ {
app.Run(context => app.Run(context =>
{ {
var accessor = app.ApplicationServices.GetRequiredService<ContextHolder>(); var accessor = app.ApplicationServices.GetRequiredService<ContextHolder>();
return context.Response.WriteAsync("HasContext:" + (accessor.Accessor.HttpContext != null)); return context.Response.WriteAsync("HasContext:" + (accessor.Accessor.HttpContext != null));
}); });
}, configureServices); })
.ConfigureServices(services =>
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<ContextHolder>();
});
var server = new TestServer(builder);
string result = await server.CreateClient().GetStringAsync("/path"); string result = await server.CreateClient().GetStringAsync("/path");
Assert.Equal("HasContext:True", result); Assert.Equal("HasContext:True", result);
@ -302,13 +324,14 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task CreateInvokesApp() public async Task CreateInvokesApp()
{ {
TestServer server = TestServer.Create(app => var builder = new WebApplicationBuilder().Configure(app =>
{ {
app.Run(context => app.Run(context =>
{ {
return context.Response.WriteAsync("CreateInvokesApp"); return context.Response.WriteAsync("CreateInvokesApp");
}); });
}); });
var server = new TestServer(builder);
string result = await server.CreateClient().GetStringAsync("/path"); string result = await server.CreateClient().GetStringAsync("/path");
Assert.Equal("CreateInvokesApp", result); Assert.Equal("CreateInvokesApp", result);
@ -318,7 +341,7 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task DisposeStreamIgnored() public async Task DisposeStreamIgnored()
{ {
TestServer server = TestServer.Create(app => var builder = new WebApplicationBuilder().Configure(app =>
{ {
app.Run(async context => app.Run(async context =>
{ {
@ -326,6 +349,7 @@ namespace Microsoft.AspNet.TestHost
context.Response.Body.Dispose(); context.Response.Body.Dispose();
}); });
}); });
var server = new TestServer(builder);
HttpResponseMessage result = await server.CreateClient().GetAsync("/"); HttpResponseMessage result = await server.CreateClient().GetAsync("/");
Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal(HttpStatusCode.OK, result.StatusCode);
@ -336,7 +360,7 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task DisposedServerThrows() public async Task DisposedServerThrows()
{ {
TestServer server = TestServer.Create(app => var builder = new WebApplicationBuilder().Configure(app =>
{ {
app.Run(async context => app.Run(async context =>
{ {
@ -344,6 +368,7 @@ namespace Microsoft.AspNet.TestHost
context.Response.Body.Dispose(); context.Response.Body.Dispose();
}); });
}); });
var server = new TestServer(builder);
HttpResponseMessage result = await server.CreateClient().GetAsync("/"); HttpResponseMessage result = await server.CreateClient().GetAsync("/");
Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal(HttpStatusCode.OK, result.StatusCode);
@ -355,15 +380,17 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task CancelAborts() public async Task CancelAborts()
{ {
TestServer server = TestServer.Create(app => var builder = new WebApplicationBuilder()
{ .Configure(app =>
app.Run(context => {
{ app.Run(context =>
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>(); {
tcs.SetCanceled(); TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
return tcs.Task; tcs.SetCanceled();
}); return tcs.Task;
}); });
});
var server = new TestServer(builder);
await Assert.ThrowsAsync<TaskCanceledException>(async () => { string result = await server.CreateClient().GetStringAsync("/path"); }); await Assert.ThrowsAsync<TaskCanceledException>(async () => { string result = await server.CreateClient().GetStringAsync("/path"); });
} }
@ -372,7 +399,9 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task CanCreateViaStartupType() public async Task CanCreateViaStartupType()
{ {
TestServer server = new TestServer(TestServer.CreateBuilder().UseStartup<TestStartup>()); var builder = new WebApplicationBuilder()
.UseStartup<TestStartup>();
var server = new TestServer(builder);
HttpResponseMessage result = await server.CreateClient().GetAsync("/"); HttpResponseMessage result = await server.CreateClient().GetAsync("/");
Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal(HttpStatusCode.OK, result.StatusCode);
Assert.Equal("FoundService:True", await result.Content.ReadAsStringAsync()); Assert.Equal("FoundService:True", await result.Content.ReadAsStringAsync());
@ -382,9 +411,11 @@ namespace Microsoft.AspNet.TestHost
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task CanCreateViaStartupTypeAndSpecifyEnv() public async Task CanCreateViaStartupTypeAndSpecifyEnv()
{ {
TestServer server = new TestServer(TestServer.CreateBuilder() var builder = new WebApplicationBuilder()
.UseStartup<TestStartup>() .UseStartup<TestStartup>()
.UseEnvironment("Foo")); .UseEnvironment("Foo");
var server = new TestServer(builder);
HttpResponseMessage result = await server.CreateClient().GetAsync("/"); HttpResponseMessage result = await server.CreateClient().GetAsync("/");
Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal(HttpStatusCode.OK, result.StatusCode);
Assert.Equal("FoundFoo:False", await result.Content.ReadAsStringAsync()); Assert.Equal("FoundFoo:False", await result.Content.ReadAsStringAsync());
@ -395,14 +426,18 @@ namespace Microsoft.AspNet.TestHost
public async Task BeginEndDiagnosticAvailable() public async Task BeginEndDiagnosticAvailable()
{ {
DiagnosticListener diagnosticListener = null; DiagnosticListener diagnosticListener = null;
var server = TestServer.Create(app =>
{ var builder = new WebApplicationBuilder()
diagnosticListener = app.ApplicationServices.GetRequiredService<DiagnosticListener>(); .Configure(app =>
app.Run(context => {
{ diagnosticListener = app.ApplicationServices.GetRequiredService<DiagnosticListener>();
return context.Response.WriteAsync("Hello World"); app.Run(context =>
}); {
}); return context.Response.WriteAsync("Hello World");
});
});
var server = new TestServer(builder);
var listener = new TestDiagnosticListener(); var listener = new TestDiagnosticListener();
diagnosticListener.SubscribeWithAdapter(listener); diagnosticListener.SubscribeWithAdapter(listener);
var result = await server.CreateClient().GetStringAsync("/path"); var result = await server.CreateClient().GetStringAsync("/path");
@ -421,7 +456,7 @@ namespace Microsoft.AspNet.TestHost
public async Task ExceptionDiagnosticAvailable() public async Task ExceptionDiagnosticAvailable()
{ {
DiagnosticListener diagnosticListener = null; DiagnosticListener diagnosticListener = null;
var server = TestServer.Create(app => var builder = new WebApplicationBuilder().Configure(app =>
{ {
diagnosticListener = app.ApplicationServices.GetRequiredService<DiagnosticListener>(); diagnosticListener = app.ApplicationServices.GetRequiredService<DiagnosticListener>();
app.Run(context => app.Run(context =>
@ -429,10 +464,12 @@ namespace Microsoft.AspNet.TestHost
throw new Exception("Test exception"); throw new Exception("Test exception");
}); });
}); });
var server = new TestServer(builder);
var listener = new TestDiagnosticListener(); var listener = new TestDiagnosticListener();
diagnosticListener.SubscribeWithAdapter(listener); diagnosticListener.SubscribeWithAdapter(listener);
await Assert.ThrowsAsync<Exception>(() => server.CreateClient().GetAsync("/path")); await Assert.ThrowsAsync<Exception>(() => server.CreateClient().GetAsync("/path"));
// This ensures that all diagnostics are completely written to the diagnostic listener // This ensures that all diagnostics are completely written to the diagnostic listener
Thread.Sleep(1000); Thread.Sleep(1000);