Created
July 7, 2017 13:28
-
-
Save poke/1c79ce431ec77f1d6de4bbb638abecb9 to your computer and use it in GitHub Desktop.
Running ASP.NET Core as Windows Service with Topshelf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.AspNetCore.Hosting; | |
using Microsoft.AspNetCore.Hosting.Server.Features; | |
using Microsoft.AspNetCore.Server.Kestrel; | |
using Microsoft.Extensions.Configuration; | |
using Microsoft.Extensions.DependencyInjection; | |
using System; | |
using System.IO; | |
namespace ExampleApp | |
{ | |
public class ApplicationHost<TStartup> | |
where TStartup : class | |
{ | |
private readonly string _launchDirectory; | |
private IWebHost _webHost; | |
private bool _stopRequested; | |
public ApplicationHost() | |
{ | |
_launchDirectory = Directory.GetCurrentDirectory(); | |
} | |
public void Start(bool launchedFromConsole) | |
{ | |
var contentRootPath = launchedFromConsole ? _launchDirectory : Directory.GetCurrentDirectory(); | |
// set up configuration | |
var config = new ConfigurationBuilder() | |
.SetBasePath(contentRootPath) | |
.AddJsonFile("hosting.json", optional: true) | |
.AddEnvironmentVariables() | |
.Build(); | |
// set up web host | |
IWebHostBuilder webHostBuilder = new WebHostBuilder() | |
.UseKestrel() | |
.UseConfiguration(config) | |
.UseContentRoot(contentRootPath) | |
.UseStartup<TStartup>(); | |
// create and run host | |
_webHost = webHostBuilder.Build(); | |
_webHost.Services.GetRequiredService<IApplicationLifetime>() | |
.ApplicationStopped.Register(() => | |
{ | |
if (!_stopRequested) | |
Stop(); | |
}); | |
_webHost.Start(); | |
// print information to console | |
if (launchedFromConsole) | |
{ | |
var hostingEnvironment = _webHost.Services.GetService<IHostingEnvironment>(); | |
Console.WriteLine($"Hosting environment: {hostingEnvironment.EnvironmentName}"); | |
Console.WriteLine($"Content root path: {hostingEnvironment.ContentRootPath}"); | |
var serverAddresses = _webHost.ServerFeatures.Get<IServerAddressesFeature>()?.Addresses; | |
foreach (var address in serverAddresses ?? Array.Empty<string>()) | |
{ | |
Console.WriteLine($"Listening on: {address}"); | |
} | |
} | |
} | |
public void Stop() | |
{ | |
_stopRequested = true; | |
_webHost?.Dispose(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Topshelf; | |
using Topshelf.Hosts; | |
namespace ExampleApp | |
{ | |
public static class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
ApplicationEntry.Run<Startup>(args); | |
} | |
public static void Run<TStartup>(string[] args) | |
where TStartup : class | |
{ | |
HostFactory.Run(x => | |
{ | |
x.Service<ApplicationHost<TStartup>>(s => | |
{ | |
s.ConstructUsing(name => new ApplicationHost<TStartup>()); | |
s.WhenStarted((svc, control) => | |
{ | |
svc.Start(control is ConsoleRunHost); | |
return true; | |
}); | |
s.WhenStopped(svc => svc.Stop()); | |
s.WhenShutdown(svc => svc.Stop()); | |
}); | |
x.StartAutomaticallyDelayed(); | |
// set default service name | |
string defaultServiceName = typeof(TStartup).Namespace; | |
if (!string.IsNullOrEmpty(defaultServiceName)) | |
x.SetServiceName(defaultServiceName); | |
}); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment