Aspnetcore.docs: Hosting non-server apps with Generic Host

Created on 26 Mar 2018  路  26Comments  路  Source: dotnet/AspNetCore.Docs

Most helpful comment

Split. Most people only need WebHostBuilder.

All 26 comments

@Tratcher Pertaining to content organization ...

Idea 1 - All-in-one topic

  • Hosting node

    • Index page covers both WebHostBuilder and HostBuilder. WebHostBuilder covered first. Perhaps, at 3.0, they swap priority with HostBuilder content moved to the top of the topic. Whenever 2.x is depreciated (way, way in the future), WebHostBuilder content is cut leaving the HostBuilder bits.

    • Subtopics pertaining to dev scenarios like background tasks are kept under this node. We only have one right now, background tasks, which would be moved under the Hosting node.

Idea 2 - Split content

  • Hosting node

    • Index page is a branch point between WebHostBuilder and HostBuilder topics defining+describing them with advice on when to use one or the other.

    • WebHostBuilder (our current Hosting content) - Swap order of topics at 3.0 placing the HostBuilder first in the TOC. Kill this topic when 2.x is depreciated in the distant future.

    • HostBuilder (new topic)

    • Subtopics under the Hosting node (e.g., background tasks)

Split. Most people only need WebHostBuilder.

@rachelappel @Rick-Anderson @scottaddie

Any objections/concerns/comments/:skull: death threats :skull: regarding Idea 2? :point_up:

The work starts 馃巿 _this weekend!_ :tada:

@Tratcher Let's firm up the plumbing (I'll provide an outline for the Generic Host topic after we get these basics resolved).

Host landing page

  • Title: Host in ASP.NET Core
  • UID: fundamentals/host/index
  • Covers:

    • Intro to hosting

    • Launch point for web host and generic host topics (and emphasizes the use of web host)

    • Common hosting configuration/setup that applies to both web and generic hosts

Web Host

  • Title: ASP.NET Core Web Host
  • UID: fundamentals/host/web-host
  • Covers WebHostBuilder

Generic Host

Hosted service topic (Updates to the topic will be on a follow-up PR)

  • Move this topic to the new host node (UID: fundamentals/host/hosted-services)
  • Link this topic into the topics above (i.e., it will have a sample for each of web host and generic host at first)

Notes

  • One way to have split these would be to have the host/index page contain the web host coverage, then add a second topic for the generic host. The problem I see with that is that we'll reach a point (3.0) where the web host will still be covered but the generic host will take the spotlight/recommendation. It's easier to manage the transition with a three-topic approach that I show above. No content swapping will be required this way. At 3.0, all we need to do is swap the emphasis to the generic host topic by moving it up in the TOC a notch and emphasizing it in the host/index page.
  • When web host depreciates (3.0?, 4.0?), I anticipate that the generic host content will move to host/index. I speculate that the depreciated web host topic will continue to be maintained for legacy app maintenance and migration purposes. This is another reason why I think a three topic approach will be best. Thoughts on this and the prior point?
  • In the current web host coverage, can you provide notes on the sections (or parts of the sections) that apply to the generic host? I plan to keep common elements in the host/index page. Otherwise if you don't have time to say, I'll research in the generic host API (combined with a bit of brute force :muscle: and rubber :duck: assistance) to see what applies to both. Here are the Hosting topic sections in question ...

Overall I think you've got a good handle on it.

I expect fundamentals/host/web-host whill chain into fundamentals/startup. There's a lot of duplication there.

Title: ASP.NET Core Generic Host

I expect fundamentals/host/web-host will chain into fundamentals/startup. There's a lot of duplication there.

I'll look at that. If we can organize the content better, this is as good a time as any to address it. I have a (small) window of time and not very many 2.1 issues left to attend (except for samples, which we won't update until RTM).

~ASP.NET Core~ Generic Host

We must include the technology name in the title of the topic somehow (an APEX directive). Do you prefer Generic Host in ASP.NET Core? In which case, the corollary for the sister topic is Web Host in ASP.NET Core.

Side note: I'll leave "Host" capitalized when specifically referring to "Web Host" and "Generic Host." I feel that these are proper nouns in these contexts.

Thanks for the notes on overlap. I'll take each in turn and work through them. I'll start that process today. I won't have the outline for the Generic Host topic until I can see which scenarios are specific to it. I'll submit a draft outline here before I start writing the Generic Host topic.

The point of Generic Host is that we're trying to seperate it from ASP.NET Core, hence the MS.Extensions name. _Generic Host in Microsoft Extensions_?

@Tratcher The Generic Host is for use in .NET scenarios. When I see "Microsoft Extensions" there, I can't obviously connect "Generic Host" to something specific to .NET.

I'm wondering about .NET Generic Host as a title because they want the technology names present for SEO purposes. I'm just a bit concerned that Generic Host in Microsoft Extensions isn't going to meet their goals for indexing the content well. ".NET" might not help much, since search results were confusing devs over which topics were "ASP.NET" and which were "ASP.NET Core;" but at least with ".NET," the title broadly classifies it as a .NET thing.

Sounds good.

@Tratcher Curious about this ... We're saying explicitly here to document "non-server apps," and I realize that there aren't IHostBuilder extensions for Kestrel yet ... BUT ... is it possible to wire it up?

I hacked together some bits in your GenericWebHost sample to see if the FakeServer could be easily replaced. This compiles but doesn't run ...

.ConfigureServices((hostContext, services) =>
{
    // Configure services
    services.TryAddSingleton<ITransportFactory, SocketTransportFactory>();
    services.AddTransient<IConfigureOptions<KestrelServerOptions>, KestrelServerOptionsSetup>();
    services.AddSingleton<IServer, KestrelServer>();
})

... and I had to change one thing in your WebHostExtensions.cs file ...

services.AddHostedService<WebHostService>();

... to ...

services.AddTransient<IHostedService, WebHostService>();

... but it :boom: at await host.RunAsync(); ...

Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll

Whatever the case with that, you want this documented explicitly for non-server scenarios, correct?

Non-server doesn't seem inclusive enough. WebHost is for a very specific HTTP scenario, where Host is for any app scenario. For now the emphasis is on WebHost because we don't have any specific scenarios moved over to Host yet.

Two questions ...

Not so important really, but just out of curiosity: Is it even possible tho to get those hacks I put up there working? ... along the lines of replacing the FakeServer to make it use Kestrel?

Question 2 ... much more important ...

Host is for any app scenario. For now the emphasis is on WebHost because we don't have any specific scenarios moved over to Host yet.

... especially the "don't have any specific scenarios moved over to Host yet" ...

Yes, but I still need show it doing something. What do you have in mind that it could do in the Generic Host sample for this topic? I see the samps you have in the repo, but do you have any additional ideas?

I recall getting it to work initially, but I couldn't check it in due to the circular dependency. I haven't tried again since and things may have drifted. From https://github.com/aspnet/KestrelHttpServer/issues/2498 it looks like at least one other person had it working recently.

Having a duplicate of the background services sample would be fine. That's how we expect more roles to work in the future.

Having a duplicate of the background services sample would be fine.

Ok, that's easy.

I'll have an outline for the topic up asap. It would've been up by now, but we've been 馃弮 CrAzY bUsY 馃弮 this week.

@Tratcher Looks like UseSetting is a web host-only concept at this time, correct?

I guess so, but it was only ever a wrapper around config.

I see what you mean ...

public IWebHostBuilder UseSetting(string key, string value)
{
    _config[key] = value;
    return this;
}

... just confirming that we won't be discussing that (today anyway) because it isn't an extension on HostBuilder.

btw -- Turns out that there isn't enough overlap between these to justify using the Host landing page to hold common content for the Web Host and Generic Host topics. Placing what little overlap there is there would be too disorganized imo. Another benefit of keeping them separate has to do with when the switchover is made. It will be a clean swap-a-roo when the time comes if these topics can stand independently.

@Tratcher We've had a lull in repo activity, so I've been 馃幐 ROCK'IN 馃幏 on this today. I've been typing content in the topic as the outline has been coming together, and I think it's looking pretty sweet thus far ...

Outline

  • .NET Generic Host

    • Introduction

    • Define "host"

    • Indicate the topic is about the Generic Host (HostBuilder)

    • Link over to the Web Host (WebHostBuilder) topic

    • Setting up a host and configuration - Some intro comments on HostBuilder

    • Configuration builder - Describe ConfigureHostConfiguration configuration + example code

    • Extension method configuration

    • Content root

    • Environment

    • Parsing configuration sections (if still relevant; let's take a look on review)

    • ConfigureAppConfiguration (note on AddConfiguration)

    • ConfigureServices

    • IHostedService

    • ConfigureLogging

    • Container configuration (described with code examples but not in the sample)

    • UseServiceProviderFactory :point_right: Set up a factory

    • ConfigureContainer

    • Manage the host (each with example code)

    • Run

    • RunAsync

    • Start

    • StopAsync

    • WaitForShutdown

    • WaitForShutdownAsync

    • UseConsoleLifetime

    • IHostingEnvironment

    • IApplicationLifetime

    • Additional resources

    • Background services topic

    • Link to the Hosting repo Generic Host samples

:point_up: If you see something out-of-whack with the order of the sections, feel free to let me know. I'll re-order sections now.

Sample

I'm using the background tasks sample. However, I'm only going to include the TimedHostedService. The rest of the example background services will be over in the full-blown background services topic. This way, the topic can focus more on the config of HostBuilder and the app.

For passing keystrokes, I'd like to surface it here with an example; however, I'd like to link over to our upcoming 2.1 background tasks sample as the implementation sample in order to keep the sample here focused on the basics.

I'm leaning in the following direction (even if this all isn't exactly right ... pseudo-coding it right now ... but feel free to :boy: :gun: shoot me down where needed) ... sort of an 脿 la carte config presentation ...

public static async Task Main(string[] args)
{
    var host = new HostBuilder()
        .ConfigureHostConfiguration(configHost =>
        {
            configHost.AddEnvironmentVariables();
            configHost.AddJsonFile("hosting.json", optional: true);
            configHost.AddCommandLine(args)
        })
        .ConfigureAppConfiguration((hostContext, configApp) =>
        {
            configApp.AddEnvironmentVariables();
            configApp.AddJsonFile("appsettings.json", optional: true);
            configApp.AddJsonFile(
                $"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", 
                optional: true);
            configApp.AddCommandLine(args);
        })
        .ConfigureServices((hostContext, services) =>
        {
            services.AddLogging();
            services.AddHostedService<TimedHostedService>();
        })
        .ConfigureLogging((hostContext, configLogging) =>
        {
            configLogging.AddConsole();
            configLogging.AddDebug();
        })
        .UseConsoleLifetime()
        .Build();

    await host.RunAsync();
}

What I like about this approach is that the structure of the sample config closely follows the topic outline. It should be easier to grok than our current hosting topic for WebHostBuilder.

I had a discussion with @anurse in the Generic Host issue (aspnet/Hosting #1163), and I'll take look at your, @anurse, comments to see if we can use any of it now. It seems like we were talking more "web"-ish things at the time that can't come in at the moment. We're largely avoiding the subject of "ConfigureWebHost" things here. However @anurse, you might want to put an :eye: on this outline and shoot a few 馃徆 arrows at me. :smile:

btw- @Tratcher, congrats to you, @davidfowl, and the team for this. I can see how great this is for hosting in ASP.NET Core and also how revolutionary this is for hosting any kind of app in any framework ever devised!

IHostedService is missing from your outline. It's the primary unit of work for Host. Everything else is supporting structure.

Not sure what "Passing console keystrokes to the app" has to do with anything. I don't know how common it will be fore these apps to be interactive consoles, that's more for demos. TimedHostedService seems more than adequate for this sample.

Remove:

    var configHost = new ConfigurationBuilder()
        .AddCommandLine(args)
        .Build();

I don't see anything from the discussion in https://github.com/aspnet/Hosting/issues/1163 that needs to be added here.

IHostedService is missing from your outline

:+1:

"Passing console keystrokes to the app"

:+1:

Remove: {ConfigurationBuilder example}

Ok ... probably should be a remark in the topic tho ... config of hosting or app via a call to AddConfiguration.

@Tratcher How are IApplicationLifetime events registered without Configure? Would one ctor-inject them into an IHostedService implementation?

Correct, Ctor inject them anywhere you need them.

I'll show an example using an IHostedService impl, and we can change it if needed on review.

I'll have this PR up soon ... final touches happening now.

Was this page helpful?
0 / 5 - 0 ratings