diff --git a/samples/SampleStartups/StartupBlockingOnStart.cs b/samples/SampleStartups/StartupBlockingOnStart.cs index 1bdecf43..cf8783fb 100644 --- a/samples/SampleStartups/StartupBlockingOnStart.cs +++ b/samples/SampleStartups/StartupBlockingOnStart.cs @@ -40,7 +40,8 @@ public static void Main(string[] args) using (host) { host.Start(); - Console.ReadLine(); + + host.WaitForShutdown(); } } } diff --git a/samples/SampleStartups/StartupHelloWorld.cs b/samples/SampleStartups/StartupHelloWorld.cs index a2f806f6..d9baf61f 100644 --- a/samples/SampleStartups/StartupHelloWorld.cs +++ b/samples/SampleStartups/StartupHelloWorld.cs @@ -6,26 +6,58 @@ namespace SampleStartups { - public class StartupHelloWorld : StartupBase + public class Program { - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public override void Configure(IApplicationBuilder app) + public static void Main() { - app.Run(async (context) => - { - await context.Response.WriteAsync("Hello World!"); - }); + var host = new WebHostBuilder() + .Run(async context => + { + await context.Response.WriteAsync("Hello World"); + }); + + host.WaitForShutdown(); + } + + public static void MainWithPort() + { + var host = new WebHostBuilder() + .Run("localhost", 8080, async context => + { + await context.Response.WriteAsync("Hello World"); + }); + + host.WaitForShutdown(); + } + + public static void MainWithMiddlewareWithPort() + { + var host = new WebHostBuilder() + .RunApplication("localhost", 8080, app => + { + // You can add middleware here + app.Run(async context => + { + await context.Response.WriteAsync("Hello World"); + }); + }); + + host.WaitForShutdown(); } - // Entry point for the application. - public static void Main(string[] args) + public static void MainWithMiddleware() { var host = new WebHostBuilder() - //.UseKestrel() - .UseStartup() - .Build(); + .RunApplication(app => + { + // You can add middleware here + app.Run(async context => + { + await context.Response.WriteAsync("Hello World"); + }); + }); - host.Run(); + host.WaitForShutdown(); } } } diff --git a/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs b/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs index 6e2b7a75..390992df 100644 --- a/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs @@ -5,6 +5,7 @@ using System.Reflection; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting.Internal; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -92,5 +93,61 @@ public static IWebHostBuilder UseDefaultServiceProvider(this IWebHostBuilder hos services.Replace(ServiceDescriptor.Singleton>(new DefaultServiceProviderFactory(options))); }); } + + /// + /// Runs a web application with the specified handler + /// + /// The to run. + /// A delegate that handles the request. + public static IWebHost Run(this IWebHostBuilder hostBuilder, RequestDelegate handler) + { + var host = hostBuilder.Configure(app => app.Run(handler)).Build(); + host.Start(); + return host; + } + + /// + /// Runs a web application with the specified handler + /// + /// The to run. + /// The host name to bind to. + /// The port to bind to. + /// A delegate that handles the request. + public static IWebHost Run(this IWebHostBuilder hostBuilder, string hostname, int port, RequestDelegate handler) + { + var host = hostBuilder.UseUrls($"http://{hostname}:{port}/") + .Configure(app => app.Run(handler)) + .Build(); + host.Start(); + return host; + } + + /// + /// Runs a web application with the specified handler + /// + /// The to run. + /// The delegate that configures the . + public static IWebHost RunApplication(this IWebHostBuilder hostBuilder, Action configure) + { + var host = hostBuilder.Configure(configure).Build(); + host.Start(); + return host; + } + + /// + /// Runs a web application with the specified handler + /// + /// The to run. + /// The host name to bind to. + /// The port to bind to. + /// The delegate that configures the . + public static IWebHost RunApplication(this IWebHostBuilder hostBuilder, string hostname, int port, Action configure) + { + var host = hostBuilder.UseUrls($"http://{hostname}:{port}/") + .Configure(configure) + .Build(); + host.Start(); + return host; + } } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Hosting/WebHostExtensions.cs b/src/Microsoft.AspNetCore.Hosting/WebHostExtensions.cs index 4fdbbf60..5da5eda2 100644 --- a/src/Microsoft.AspNetCore.Hosting/WebHostExtensions.cs +++ b/src/Microsoft.AspNetCore.Hosting/WebHostExtensions.cs @@ -14,11 +14,86 @@ namespace Microsoft.AspNetCore.Hosting { public static class WebHostExtensions { + /// + /// Blocks the calling thread until the web application shuts down. + /// + /// The to wait for shutdown + public static void WaitForShutdown(this IWebHost host) + { + WaitForSystemShutdown(host, (token, message) => host.WaitForShutdown(token, message)); + } + + /// + /// Blocks the calling thread until the web application shuts down. + /// + /// The to wait for shutdown + /// The token to trigger shutdown. + public static void WaitForShutdown(this IWebHost host, CancellationToken token) + { + host.WaitForShutdown(token, shutdownMessage: null); + } + /// /// Runs a web application and block the calling thread until host shutdown. /// /// The to run. public static void Run(this IWebHost host) + { + WaitForSystemShutdown(host, (token, message) => host.Run(token, message)); + } + + /// + /// Runs a web application and block the calling thread until token is triggered or shutdown is triggered. + /// + /// The to run. + /// The token to trigger shutdown. + public static void Run(this IWebHost host, CancellationToken token) + { + host.Run(token, shutdownMessage: null); + } + + private static void Run(this IWebHost host, CancellationToken token, string shutdownMessage) + { + using (host) + { + host.Start(); + + host.WaitForShutdown(token, shutdownMessage); + } + } + + private static void WaitForShutdown(this IWebHost host, CancellationToken token, string shutdownMessage) + { + var hostingEnvironment = host.Services.GetService(); + var applicationLifetime = host.Services.GetService(); + + Console.WriteLine($"Hosting environment: {hostingEnvironment.EnvironmentName}"); + Console.WriteLine($"Content root path: {hostingEnvironment.ContentRootPath}"); + + var serverAddresses = host.ServerFeatures.Get()?.Addresses; + if (serverAddresses != null) + { + foreach (var address in serverAddresses) + { + Console.WriteLine($"Now listening on: {address}"); + } + } + + if (!string.IsNullOrEmpty(shutdownMessage)) + { + Console.WriteLine(shutdownMessage); + } + + token.Register(state => + { + ((IApplicationLifetime)state).StopApplication(); + }, + applicationLifetime); + + applicationLifetime.ApplicationStopping.WaitHandle.WaitOne(); + } + + private static void WaitForSystemShutdown(this IWebHost host, Action execute) { var done = new ManualResetEventSlim(false); using (var cts = new CancellationTokenSource()) @@ -48,55 +123,9 @@ public static void Run(this IWebHost host) eventArgs.Cancel = true; }; - host.Run(cts.Token, "Application started. Press Ctrl+C to shut down."); + execute(cts.Token, "Application started. Press Ctrl+C to shut down."); done.Set(); } } - - /// - /// Runs a web application and block the calling thread until token is triggered or shutdown is triggered. - /// - /// The to run. - /// The token to trigger shutdown. - public static void Run(this IWebHost host, CancellationToken token) - { - host.Run(token, shutdownMessage: null); - } - - private static void Run(this IWebHost host, CancellationToken token, string shutdownMessage) - { - using (host) - { - host.Start(); - - var hostingEnvironment = host.Services.GetService(); - var applicationLifetime = host.Services.GetService(); - - Console.WriteLine($"Hosting environment: {hostingEnvironment.EnvironmentName}"); - Console.WriteLine($"Content root path: {hostingEnvironment.ContentRootPath}"); - - var serverAddresses = host.ServerFeatures.Get()?.Addresses; - if (serverAddresses != null) - { - foreach (var address in serverAddresses) - { - Console.WriteLine($"Now listening on: {address}"); - } - } - - if (!string.IsNullOrEmpty(shutdownMessage)) - { - Console.WriteLine(shutdownMessage); - } - - token.Register(state => - { - ((IApplicationLifetime)state).StopApplication(); - }, - applicationLifetime); - - applicationLifetime.ApplicationStopping.WaitHandle.WaitOne(); - } - } } } \ No newline at end of file