Use new generic host UseDefaultServiceProvider call (#5703)

This commit is contained in:
Chris Ross 2018-12-19 12:17:58 -08:00 committed by GitHub
parent e21fe567b2
commit 03867f08ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 19 additions and 215 deletions

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
@ -196,16 +196,12 @@ namespace Microsoft.AspNetCore.Hosting.Internal
public IWebHostBuilder UseDefaultServiceProvider(Action<WebHostBuilderContext, ServiceProviderOptions> configure) public IWebHostBuilder UseDefaultServiceProvider(Action<WebHostBuilderContext, ServiceProviderOptions> configure)
{ {
// REVIEW: This is a hack to change the builder with the HostBuilderContext in scope, _builder.UseServiceProviderFactory(context =>
// we're not actually using configuration here
_builder.ConfigureAppConfiguration((context, _) =>
{ {
var webHostBuilderContext = GetWebHostBuilderContext(context); var webHostBuilderContext = GetWebHostBuilderContext(context);
var options = new ServiceProviderOptions(); var options = new ServiceProviderOptions();
configure(webHostBuilderContext, options); configure(webHostBuilderContext, options);
return new DefaultServiceProviderFactory(options);
// This is only fine because this runs last
_builder.UseServiceProviderFactory(new DefaultServiceProviderFactory(options));
}); });
return this; return this;
@ -373,4 +369,4 @@ namespace Microsoft.AspNetCore.Hosting.Internal
} }
} }
} }
} }

View File

@ -1,32 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace GenericWebHost
{
// We can't reference real servers in this sample without creating a circular repo dependency.
// This fake server lets us at least run the code.
public class FakeServer : IServer
{
public IFeatureCollection Features => new FeatureCollection();
public Task StartAsync<TContext>(IHttpApplication<TContext> application, CancellationToken cancellationToken) => Task.CompletedTask;
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public void Dispose()
{
}
}
public static class FakeServerWebHostBuilderExtensions
{
public static IHostBuilder UseFakeServer(this IHostBuilder builder)
{
return builder.ConfigureServices((builderContext, services) => services.AddSingleton<IServer, FakeServer>());
}
}
}

View File

@ -9,10 +9,8 @@
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.AspNetCore.Hosting" /> <Reference Include="Microsoft.AspNetCore.Hosting" />
<Reference Include="Microsoft.AspNetCore.Server.Kestrel" />
<Reference Include="Microsoft.Extensions.Hosting" /> <Reference Include="Microsoft.Extensions.Hosting" />
<Reference Include="Microsoft.Extensions.Configuration.CommandLine" />
<Reference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
<Reference Include="Microsoft.Extensions.Configuration.Json" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,4 +1,4 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
@ -11,17 +11,11 @@ namespace GenericWebHost
{ {
public static async Task Main(string[] args) public static async Task Main(string[] args)
{ {
var host = new HostBuilder() var host = Host.CreateDefaultBuilder()
.ConfigureAppConfiguration((hostContext, config) =>
{
config.AddEnvironmentVariables();
config.AddJsonFile("appsettings.json", optional: true);
config.AddCommandLine(args);
})
.UseFakeServer()
.ConfigureWebHost(builder => .ConfigureWebHost(builder =>
{ {
builder.Configure(app => builder.UseKestrel()
.Configure(app =>
{ {
app.Run(async (context) => app.Run(async (context) =>
{ {
@ -29,7 +23,6 @@ namespace GenericWebHost
}); });
}); });
}) })
.UseConsoleLifetime()
.Build(); .Build();
await host.RunAsync(); await host.RunAsync();

View File

@ -1,43 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.ObjectPool;
namespace GenericWebHost
{
public static class WebHostExtensions
{
public static IHostBuilder ConfigureWebHost(this IHostBuilder builder, Action<HostBuilderContext, IApplicationBuilder> configureApp)
{
return builder.ConfigureServices((bulderContext, services) =>
{
services.Configure<WebHostServiceOptions>(options =>
{
options.ConfigureApp = configureApp;
});
services.AddHostedService<WebHostService>();
var listener = new DiagnosticListener("Microsoft.AspNetCore");
services.AddSingleton<DiagnosticListener>(listener);
services.AddSingleton<DiagnosticSource>(listener);
services.AddTransient<IHttpContextFactory, HttpContextFactory>();
services.AddScoped<IMiddlewareFactory, MiddlewareFactory>();
// Conjure up a RequestServices
services.AddTransient<IStartupFilter, AutoRequestServicesStartupFilter>();
services.AddTransient<IServiceProviderFactory<IServiceCollection>, DefaultServiceProviderFactory>();
// Ensure object pooling is available everywhere.
services.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
});
}
}
}

View File

@ -1,62 +0,0 @@
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder.Internal;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace GenericWebHost
{
internal class WebHostService : IHostedService
{
public WebHostService(IOptions<WebHostServiceOptions> options, IServiceProvider services, HostBuilderContext hostBuilderContext, IServer server,
ILogger<WebHostService> logger, DiagnosticListener diagnosticListener, IHttpContextFactory httpContextFactory)
{
Options = options?.Value ?? throw new System.ArgumentNullException(nameof(options));
if (Options.ConfigureApp == null)
{
throw new ArgumentException(nameof(Options.ConfigureApp));
}
Services = services ?? throw new ArgumentNullException(nameof(services));
HostBuilderContext = hostBuilderContext ?? throw new ArgumentNullException(nameof(hostBuilderContext));
Server = server ?? throw new ArgumentNullException(nameof(server));
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
DiagnosticListener = diagnosticListener ?? throw new ArgumentNullException(nameof(diagnosticListener));
HttpContextFactory = httpContextFactory ?? throw new ArgumentNullException(nameof(httpContextFactory));
}
public WebHostServiceOptions Options { get; }
public IServiceProvider Services { get; }
public HostBuilderContext HostBuilderContext { get; }
public IServer Server { get; }
public ILogger<WebHostService> Logger { get; }
public DiagnosticListener DiagnosticListener { get; }
public IHttpContextFactory HttpContextFactory { get; }
public Task StartAsync(CancellationToken cancellationToken)
{
Server.Features.Get<IServerAddressesFeature>()?.Addresses.Add("http://localhost:5000");
var builder = new ApplicationBuilder(Services, Server.Features);
Options.ConfigureApp(HostBuilderContext, builder);
var app = builder.Build();
var httpApp = new HostingApplication(app, Logger, DiagnosticListener, HttpContextFactory);
return Server.StartAsync(httpApp, cancellationToken);
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Server.StopAsync(cancellationToken);
}
}
}

View File

@ -1,11 +0,0 @@
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;
namespace GenericWebHost
{
public class WebHostServiceOptions
{
public Action<HostBuilderContext, IApplicationBuilder> ConfigureApp { get; internal set; }
}
}

View File

@ -1,32 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.DependencyInjection;
namespace SampleStartups
{
// We can't reference real servers in this sample without creating a circular repo dependency.
// This fake server lets us at least run the code.
public class FakeServer : IServer
{
public IFeatureCollection Features => new FeatureCollection();
public Task StartAsync<TContext>(IHttpApplication<TContext> application, CancellationToken cancellationToken) => Task.CompletedTask;
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public void Dispose()
{
}
}
public static class FakeServerWebHostBuilderExtensions
{
public static IWebHostBuilder UseFakeServer(this IWebHostBuilder builder)
{
return builder.ConfigureServices(services => services.AddSingleton<IServer, FakeServer>());
}
}
}

View File

@ -1,13 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
<StartupObject>SampleStartups.StartupInjection</StartupObject> <StartupObject>SampleStartups.StartupBlockingOnStart</StartupObject>
<OutputType>exe</OutputType> <OutputType>exe</OutputType>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.AspNetCore.Hosting" /> <Reference Include="Microsoft.AspNetCore.Hosting" />
<Reference Include="Microsoft.AspNetCore.Server.Kestrel" />
<Reference Include="Microsoft.Extensions.Configuration.CommandLine" /> <Reference Include="Microsoft.Extensions.Configuration.CommandLine" />
<Reference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" /> <Reference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
<Reference Include="Microsoft.Extensions.Configuration.Json" /> <Reference Include="Microsoft.Extensions.Configuration.Json" />

View File

@ -33,7 +33,7 @@ namespace SampleStartups
var host = new WebHostBuilder() var host = new WebHostBuilder()
.UseConfiguration(config) .UseConfiguration(config)
.UseFakeServer() .UseKestrel()
.UseStartup<StartupBlockingOnStart>() .UseStartup<StartupBlockingOnStart>()
.Build(); .Build();

View File

@ -25,7 +25,7 @@ namespace SampleStartups
var host = new WebHostBuilder() var host = new WebHostBuilder()
.UseConfiguration(config) .UseConfiguration(config)
.UseFakeServer() .UseKestrel()
.UseStartup<StartupConfigureAddresses>() .UseStartup<StartupConfigureAddresses>()
.UseUrls("http://localhost:5000", "http://localhost:5001") .UseUrls("http://localhost:5000", "http://localhost:5001")
.Build(); .Build();

View File

@ -30,8 +30,7 @@ namespace SampleStartups
public void Start() public void Start()
{ {
_host = new WebHostBuilder() _host = new WebHostBuilder()
//.UseKestrel() .UseKestrel()
.UseFakeServer()
.UseStartup<StartupExternallyControlled>() .UseStartup<StartupExternallyControlled>()
.Start(_urls.ToArray()); .Start(_urls.ToArray());
} }

View File

@ -22,8 +22,7 @@ namespace SampleStartups
var host = new WebHostBuilder() var host = new WebHostBuilder()
.UseConfiguration(config) // Default set of configurations to use, may be subsequently overridden .UseConfiguration(config) // Default set of configurations to use, may be subsequently overridden
//.UseKestrel() .UseKestrel()
.UseFakeServer()
.UseContentRoot(Directory.GetCurrentDirectory()) // Override the content root with the current directory .UseContentRoot(Directory.GetCurrentDirectory()) // Override the content root with the current directory
.UseUrls("http://*:1000", "https://*:902") .UseUrls("http://*:1000", "https://*:902")
.UseEnvironment(EnvironmentName.Development) .UseEnvironment(EnvironmentName.Development)

View File

@ -21,8 +21,7 @@ namespace SampleStartups
public static void Main(string[] args) public static void Main(string[] args)
{ {
var host = new WebHostBuilder() var host = new WebHostBuilder()
//.UseKestrel() .UseKestrel()
.UseFakeServer()
.UseStartup<StartupHelloWorld>() .UseStartup<StartupHelloWorld>()
.Build(); .Build();

View File

@ -1,4 +1,4 @@
using System; using System;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -20,8 +20,7 @@ namespace SampleStartups
public static void Main(string[] args) public static void Main(string[] args)
{ {
var host = new WebHostBuilder() var host = new WebHostBuilder()
//.UseKestrel() .UseKestrel()
.UseFakeServer()
// Each of these three sets ApplicationName to the current assembly, which is needed in order to // Each of these three sets ApplicationName to the current assembly, which is needed in order to
// scan the assembly for HostingStartupAttributes. // scan the assembly for HostingStartupAttributes.
// .UseSetting(WebHostDefaults.ApplicationKey, "SampleStartups") // .UseSetting(WebHostDefaults.ApplicationKey, "SampleStartups")