简体   繁体   中英

ASP.NET 5 / MVC 6 Console Hosted App

In MVC5, I had a console application that would use Microsoft.Owin.Hosting.WebApp.Start(...) to host a bunch of controllers that would be dynamically loaded from assemblies placed in an external folder and run some custom initialization on them via API call. This way I could pass parameters to the initialization method that were determined at runtime (and would not be as clunky as maintaining config files).

In MVC6, the self-hosting is now done, as far as I know, by the DNX runtime using Microsoft.AspNet.Hosting, but this is all done via command line. Is there a way I can self-host from within a C# console application so I can keep this initialization architecture?

...I had a console application that would use Microsoft.Owin.Hosting.WebApp.Start(...) to host [and to] pass parameters to the initialization method that were determined at runtime...

In ASP.NET 4.x we self-host within a console application using an OWIN host. We run our MyApp.exe directly. Its Main() method calls WebApp.Start() to create the OWIN host. We use an instance of an IAppBuilder to build up the HTTP pipeline via appBuilder.Use() and chain it all together with appBuilder.Build() . This is all within the Microsoft.Owin.Hosting namespace.

Is there a way I can self-host from within a C# console application so I can keep this initialization architecture?

In ASP.NET Core rc2 we self-host inside a console application using an IWebHost . (This is not an OWIN host though OWIN inspired it.) We run our MyApp.exe directly. The Main() method creates a new WebHostBuilder() , which we use to build up the HTTP pipeline via webHostBuilder.Use() , chaining it all together with webHostBuilder.Build() . This is all within the Microsoft.AspNet.Hosting namespace.

Regarding Pinpoint's answer, in ASP.NET Core rc1 we need to run dnx.exe instead of running our app directly. The work of the WebHostBuilder is hidden inside the dnx.exe executable. Dnx.exe also starts-up our application. Our application's Main() method calls WebApplication.Run() , after which we use an instance of IApplicationBuilder to add middleware to the HTTP pipeline via calls to appBuilder.Use() . Both our application and dnx.exe shared the responsibility of creating/configuring the host. It's convoluted and I am glad that this changed in rc2. I supposed that in rc1 the equivalent of OWIN's WebApp.Start() is WebApplication.Run() .

ASP.NET 4.x            ASP.NET Core rc1           ASP.NET Core rc2

N/A                    Dnx.exe                      N/A
MyApp.exe              MyApp.dll                    MyApp.exe
Main(args)             Main(args)                   Main(args)
WebApp.Start()         WebApplication.Run(args)     N/A   
appBuilder.Use()       appBuilder.Use()             webHostBuilder.Use()
appBuilder.Build()     N/A                          webHostBuilder.Build()

Some References

http://www.asp.net/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api

https://msdn.microsoft.com/en-us/library/microsoft.owin.hosting.webapp%28v=vs.113%29.aspx

Katana's WebApp static class has been replaced by WebHostBuilder , that offers a much more flexible approach: https://github.com/aspnet/Hosting/blob/dev/src/Microsoft.AspNet.Hosting/WebHostBuilder.cs .

You've probably already used this API without realizing it, as it's the component used by the hosting block when you register a new web command in your project.json (eg Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:54540 ) and run it using dnx (eg dnx . web ):

namespace Microsoft.AspNet.Hosting
{
    public class Program
    {
        private const string HostingIniFile = "Microsoft.AspNet.Hosting.ini";
        private const string ConfigFileKey = "config";

        private readonly IServiceProvider _serviceProvider;

        public Program(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }

        public void Main(string[] args)
        {
            // Allow the location of the ini file to be specified via a --config command line arg
            var tempBuilder = new ConfigurationBuilder().AddCommandLine(args);
            var tempConfig = tempBuilder.Build();
            var configFilePath = tempConfig[ConfigFileKey] ?? HostingIniFile;

            var appBasePath = _serviceProvider.GetRequiredService<IApplicationEnvironment>().ApplicationBasePath;
            var builder = new ConfigurationBuilder(appBasePath);
            builder.AddIniFile(configFilePath, optional: true);
            builder.AddEnvironmentVariables();
            builder.AddCommandLine(args);
            var config = builder.Build();

            var host = new WebHostBuilder(_serviceProvider, config).Build();
            using (host.Start())
            {
                Console.WriteLine("Started");
                var appShutdownService = host.ApplicationServices.GetRequiredService<IApplicationShutdown>();
                Console.CancelKeyPress += (sender, eventArgs) =>
                {
                    appShutdownService.RequestShutdown();
                    // Don't terminate the process immediately, wait for the Main thread to exit gracefully.
                    eventArgs.Cancel = true;
                };
                appShutdownService.ShutdownRequested.WaitHandle.WaitOne();
            }
        }
    }
}

https://github.com/aspnet/Hosting/blob/dev/src/Microsoft.AspNet.Hosting/Program.cs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM