Adds new WebHost API for creating IWebHost & IWebHostBuilder with defaults:

- #24
This commit is contained in:
damianedwards 2017-04-06 18:09:58 -07:00 committed by John Luo
parent 198fe34813
commit 55d50b2d41
11 changed files with 360 additions and 4 deletions

View File

@ -20,8 +20,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{F92CB7A1
build\repo.targets = build\repo.targets
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.RuntimeStore", "src\Microsoft.AspNetCore.RuntimeStore\Microsoft.AspNetCore.RuntimeStore.csproj", "{A4585E19-FC49-43B4-9416-0BD3120EAD32}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{192F583C-C4CA-43E5-B31C-D21B7806E274}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp", "samples\SampleApp\SampleApp.csproj", "{AF5BB04E-92F7-4737-8B98-F86F6244FAB2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -36,6 +41,10 @@ Global
{CC8F551E-213A-45E8-AECA-507C4DB4F164}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CC8F551E-213A-45E8-AECA-507C4DB4F164}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CC8F551E-213A-45E8-AECA-507C4DB4F164}.Release|Any CPU.Build.0 = Release|Any CPU
{AF5BB04E-92F7-4737-8B98-F86F6244FAB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF5BB04E-92F7-4737-8B98-F86F6244FAB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF5BB04E-92F7-4737-8B98-F86F6244FAB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF5BB04E-92F7-4737-8B98-F86F6244FAB2}.Release|Any CPU.Build.0 = Release|Any CPU
{A4585E19-FC49-43B4-9416-0BD3120EAD32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A4585E19-FC49-43B4-9416-0BD3120EAD32}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A4585E19-FC49-43B4-9416-0BD3120EAD32}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -48,6 +57,7 @@ Global
{6F3D43F7-9546-4B41-AF04-CF4708B62051} = {ED834E68-51C3-4ADE-ACC8-6BA6D4207C09}
{CC8F551E-213A-45E8-AECA-507C4DB4F164} = {ED834E68-51C3-4ADE-ACC8-6BA6D4207C09}
{F92CB7A1-C38E-408C-A7EC-A5C040D041E1} = {97D53BEB-A511-4FBE-B784-AB407D9A219F}
{AF5BB04E-92F7-4737-8B98-F86F6244FAB2} = {192F583C-C4CA-43E5-B31C-D21B7806E274}
{A4585E19-FC49-43B4-9416-0BD3120EAD32} = {ED834E68-51C3-4ADE-ACC8-6BA6D4207C09}
EndGlobalSection
EndGlobal

BIN
build/Key.snk Normal file

Binary file not shown.

View File

@ -31,6 +31,8 @@
<MetaPackagePackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<MetaPackagePackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<MetaPackagePackageReference Include="Microsoft.Extensions.Configuration.Json" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<MetaPackagePackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<MetaPackagePackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<MetaPackagePackageReference Include="Microsoft.Extensions.Logging" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<MetaPackagePackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<MetaPackagePackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
@ -129,10 +131,8 @@
<FullMetaPackagePackageReference Include="Microsoft.Extensions.Configuration" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<FullMetaPackagePackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<FullMetaPackagePackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<FullMetaPackagePackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<FullMetaPackagePackageReference Include="Microsoft.Extensions.Configuration.DockerSecrets" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<FullMetaPackagePackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<FullMetaPackagePackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<FullMetaPackagePackageReference Include="Microsoft.Extensions.Configuration.Xml" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<FullMetaPackagePackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(AspNetCoreVersion)" PrivateAssets="None" />
<FullMetaPackagePackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(AspNetCoreVersion)" PrivateAssets="None" />

View File

@ -5,5 +5,6 @@
<CoreFxVersion>4.3.0</CoreFxVersion>
<InternalAspNetCoreSdkVersion>2.0.0-*</InternalAspNetCoreSdkVersion>
<NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>
<RuntimeFrameworkVersion>2.0.0-*</RuntimeFrameworkVersion>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,63 @@
using System;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
namespace SampleApp
{
public class Program
{
public static void Main(string[] args)
{
//HelloWorld();
//CustomUrl();
Router();
//StartupClass(args);
}
private static void HelloWorld()
{
var host = WebHost.Start(context => context.Response.WriteAsync("Hello, World!"));
//host.WaitForShutdown(); // TODO: This method needs to be added to Hosting
Console.WriteLine("Press any key to shutdown...");
Console.ReadKey();
}
private static void CustomUrl()
{
// Changing the listening URL
var host = WebHost.Start("http://localhost:8080", context => context.Response.WriteAsync("Hello, World!"));
//host.WaitForShutdown(); // TODO: This method needs to be added to Hosting
Console.WriteLine("Press any key to shutdown...");
Console.ReadKey();
}
private static void Router()
{
// Using a router
var host = WebHost.Start(router => router
.MapGet("hello/{name}", (req, res, data) => res.WriteAsync($"Hello, {data.Values["name"]}"))
.MapGet("goodbye/{name}", (req, res, data) => res.WriteAsync($"Goodbye, {data.Values["name"]}"))
.MapGet("throw/{message?}", (req, res, data) => throw new Exception((string)data.Values["message"] ?? "Uh oh!"))
.MapGet("{greeting}/{name}", (req, res, data) => res.WriteAsync($"{data.Values["greeting"]}, {data.Values["name"]}"))
.MapGet("", (req, res, data) => res.WriteAsync($"Hello, World!"))
);
//host.WaitForShutdown(); // TODO: This method needs to be added to Hosting
Console.WriteLine("Press any key to shutdown...");
Console.ReadKey();
}
private static void StartupClass(string[] args)
{
// Using defaults with a Startup class
var host = WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
host.Run();
}
}
}

View File

@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:53432/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"SampleApp": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:53433"
}
}
}

View File

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<UserSecretsId>aspnetcore-MetaPackagesSampleApp-20170406180413</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore\Microsoft.AspNetCore.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace SampleApp
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Run(async (context) =>
{
await context.Response.WriteAsync($"Hello from {nameof(Startup)}!");
});
}
}
}

View File

@ -3,10 +3,14 @@
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<IncludeBuildOutput>false</IncludeBuildOutput>
<TargetFramework>netstandard1.3</TargetFramework>
<IncludeBuildOutput>true</IncludeBuildOutput>
<TargetFramework>netstandard1.5</TargetFramework>
<PackageTags>aspnetcore</PackageTags>
<Description>Microsoft.AspNetCore</Description>
<GenerateUserSecretsAttribute>false</GenerateUserSecretsAttribute>
<AssemblyOriginatorKeyFile>..\..\build\Key.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
</PropertyGroup>
<ItemGroup>

View File

@ -0,0 +1,179 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore
{
/// <summary>
/// Provides convenience methods for creating instances of <see cref="IWebHost"/> and <see cref="IWebHostBuilder"/> with pre-configured defaults.
/// </summary>
public static class WebHost
{
/// <summary>
/// Initializes and starts a new <see cref="IWebHost"/> with pre-configured defaults.
/// See <see cref="WebHost.CreateDefaultBuilder"/> for details.
/// </summary>
/// <param name="app">A delegate that handles requests to the application.</param>
/// <returns>A started <see cref="IWebHost"/> that hosts the application.</returns>
public static IWebHost Start(RequestDelegate app) =>
Start(null, app);
/// <summary>
/// Initializes and starts a new <see cref="IWebHost"/> with pre-configured defaults.
/// See <see cref="WebHost.CreateDefaultBuilder"/> for details.
/// </summary>
/// <param name="url">The URL the hosted application will listen on.</param>
/// <param name="app">A delegate that handles requests to the application.</param>
/// <returns>A started <see cref="IWebHost"/> that hosts the application.</returns>
public static IWebHost Start(string url, RequestDelegate app) =>
StartWith(url, appBuilder => appBuilder.Run(app));
/// <summary>
/// Initializes and starts a new <see cref="IWebHost"/> with pre-configured defaults.
/// See <see cref="WebHost.CreateDefaultBuilder"/> for details.
/// </summary>
/// <param name="routeBuilder">A delegate that configures the router for handling requests to the application.</param>
/// <returns>A started <see cref="IWebHost"/> that hosts the application.</returns>
public static IWebHost Start(Action<IRouteBuilder> routeBuilder) =>
Start(null, routeBuilder);
/// <summary>
/// Initializes and starts a new <see cref="IWebHost"/> with pre-configured defaults.
/// See <see cref="WebHost.CreateDefaultBuilder"/> for details.
/// </summary>
/// <param name="url">The URL the hosted application will listen on.</param>
/// <param name="routeBuilder">A delegate that configures the router for handling requests to the application.</param>
/// <returns>A started <see cref="IWebHost"/> that hosts the application.</returns>
public static IWebHost Start(string url, Action<IRouteBuilder> routeBuilder) =>
StartWith(url, services => services.AddRouting(), app => app.UseRouter(routeBuilder));
/// <summary>
/// Initializes and starts a new <see cref="IWebHost"/> with pre-configured defaults.
/// See <see cref="WebHost.CreateDefaultBuilder"/> for details.
/// </summary>
/// <param name="app">A delegate that handles requests to the application.</param>
/// <returns>A started <see cref="IWebHost"/> that hosts the application.</returns>
public static IWebHost StartWith(Action<IApplicationBuilder> app) =>
StartWith(null, app);
/// <summary>
/// Initializes and starts a new <see cref="IWebHost"/> with pre-configured defaults.
/// See <see cref="WebHost.CreateDefaultBuilder"/> for details.
/// </summary>
/// <param name="url">The URL the hosted application will listen on.</param>
/// <param name="app">The delegate that configures the <see cref="IApplicationBuilder"/>.</param>
/// <returns>A started <see cref="IWebHost"/> that hosts the application.</returns>
public static IWebHost StartWith(string url, Action<IApplicationBuilder> app) =>
StartWith(url, null, app);
private static IWebHost StartWith(string url, Action<IServiceCollection> configureServices, Action<IApplicationBuilder> app)
{
var builder = CreateDefaultBuilder();
if (!string.IsNullOrEmpty(url))
{
builder.UseUrls(url);
}
if (configureServices != null)
{
builder.ConfigureServices(configureServices);
}
var host = builder
.Configure(app)
.Build();
host.Start();
return host;
}
/// <summary>
/// Initializes a new instance of the <see cref="WebHostBuilder"/> class with pre-configured defaults.
/// </summary>
/// <remarks>
/// The following defaults are applied to the returned <see cref="WebHostBuilder"/>:
/// use Kestrel as the web server,
/// set the <see cref="IHostingEnvironment.ContentRootPath"/> to the result of <see cref="Directory.GetCurrentDirectory()"/>,
/// load <see cref="IConfiguration"/> from 'appsettings.json' and 'appsettings.[<see cref="IHostingEnvironment.EnvironmentName"/>].json',
/// load <see cref="IConfiguration"/> from User Secrets when <see cref="IHostingEnvironment.EnvironmentName"/> is 'Development' using the entry assembly,
/// load <see cref="IConfiguration"/> from environment variables,
/// configures the <see cref="ILoggerFactory"/> to log to the console,
/// enables IIS integration,
/// and adds the developer exception page when <see cref="IHostingEnvironment.EnvironmentName"/> is 'Development'
/// </remarks>
/// <returns>The initialized <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder CreateDefaultBuilder() =>
CreateDefaultBuilder(null);
/// <summary>
/// Initializes a new instance of the <see cref="WebHostBuilder"/> class with pre-configured defaults.
/// </summary>
/// <remarks>
/// The following defaults are applied to the returned <see cref="WebHostBuilder"/>:
/// use Kestrel as the web server,
/// set the <see cref="IHostingEnvironment.ContentRootPath"/> to the result of <see cref="Directory.GetCurrentDirectory()"/>,
/// load <see cref="IConfiguration"/> from 'appsettings.json' and 'appsettings.[<see cref="IHostingEnvironment.EnvironmentName"/>].json',
/// load <see cref="IConfiguration"/> from User Secrets when <see cref="IHostingEnvironment.EnvironmentName"/> is 'Development' using the entry assembly,
/// load <see cref="IConfiguration"/> from environment variables,
/// load <see cref="IConfiguration"/> from supplied command line args,
/// configures the <see cref="ILoggerFactory"/> to log to the console,
/// enables IIS integration,
/// and adds the developer exception page when <see cref="IHostingEnvironment.EnvironmentName"/> is 'Development'
/// </remarks>
/// <param name="args">The command line args.</param>
/// <returns>The initialized <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
if (env.IsDevelopment())
{
var appAssembly = Assembly.GetEntryAssembly();
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureLogging(logging =>
{
logging.AddConsole();
})
// TODO: Remove this when ANCM injects it by default
.UseIISIntegration()
.ConfigureServices(services =>
{
services.AddSingleton<IStartupFilter, WebHostStartupFilter>();
});
return builder;
}
}
}

View File

@ -0,0 +1,26 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore
{
internal class WebHostStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return app =>
{
var env = app.ApplicationServices.GetService<IHostingEnvironment>();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
next(app);
};
}
}
}