Support the Extensions.Abstractions from Hosting.Abstractions (#1259)

- The goal here is to enable components that use hosting abstractions to use
the web host. It lets us start to decouple components from the web host abstractions
where possible while not breaking any existing components. This will allow things
to work in both the generic host and the web host. The one snafu is the WebHostBuilderContext
which has an IHostingEnvironment typed as the AspNetCore.Abstractions type.
- Updated tests.

#1218
This commit is contained in:
David Fowler 2017-11-09 21:24:30 -08:00 committed by GitHub
parent 05fd382b93
commit a78b9c7490
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 52 additions and 6 deletions

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
/// <summary>
/// Allows consumers to perform cleanup during a graceful shutdown.
/// </summary>
public class ApplicationLifetime : IApplicationLifetime
public class ApplicationLifetime : IApplicationLifetime, Extensions.Hosting.IApplicationLifetime
{
private readonly CancellationTokenSource _startedSource = new CancellationTokenSource();
private readonly CancellationTokenSource _stoppingSource = new CancellationTokenSource();

View File

@ -5,7 +5,7 @@ using Microsoft.Extensions.FileProviders;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class HostingEnvironment : IHostingEnvironment
public class HostingEnvironment : IHostingEnvironment, Extensions.Hosting.IHostingEnvironment
{
public string EnvironmentName { get; set; } = Hosting.EnvironmentName.Production;

View File

@ -76,6 +76,11 @@ namespace Microsoft.AspNetCore.Hosting.Internal
_applicationServiceCollection = appServices;
_hostingServiceProvider = hostingServiceProvider;
_applicationServiceCollection.AddSingleton<IApplicationLifetime, ApplicationLifetime>();
// There's no way to to register multiple service types per definition. See https://github.com/aspnet/DependencyInjection/issues/360
_applicationServiceCollection.AddSingleton(sp =>
{
return sp.GetRequiredService<IApplicationLifetime>() as Extensions.Hosting.IApplicationLifetime;
});
_applicationServiceCollection.AddSingleton<HostedServiceExecutor>();
}

View File

@ -10,6 +10,7 @@
<ItemGroup>
<ProjectReference Include="..\Microsoft.AspNetCore.Hosting.Abstractions\Microsoft.AspNetCore.Hosting.Abstractions.csproj" />
<ProjectReference Include="..\Microsoft.Extensions.Hosting.Abstractions\Microsoft.Extensions.Hosting.Abstractions.csproj" />
</ItemGroup>
<ItemGroup>

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Hosting
/// </summary>
public class WebHostBuilder : IWebHostBuilder
{
private readonly IHostingEnvironment _hostingEnvironment;
private readonly HostingEnvironment _hostingEnvironment;
private readonly List<Action<WebHostBuilderContext, IServiceCollection>> _configureServicesDelegates;
private IConfiguration _config;
@ -239,7 +239,8 @@ namespace Microsoft.AspNetCore.Hosting
var services = new ServiceCollection();
services.AddSingleton(_options);
services.AddSingleton(_hostingEnvironment);
services.AddSingleton<IHostingEnvironment>(_hostingEnvironment);
services.AddSingleton<Extensions.Hosting.IHostingEnvironment>(_hostingEnvironment);
services.AddSingleton(_context);
var builder = new ConfigurationBuilder()

View File

@ -526,6 +526,7 @@ namespace Microsoft.AspNetCore.Hosting
.Build())
{
Assert.Equal(expected, host.Services.GetService<IHostingEnvironment>().EnvironmentName);
Assert.Equal(expected, host.Services.GetService<Extensions.Hosting.IHostingEnvironment>().EnvironmentName);
}
}
@ -568,6 +569,7 @@ namespace Microsoft.AspNetCore.Hosting
.Build())
{
Assert.Equal("/", host.Services.GetService<IHostingEnvironment>().ContentRootPath);
Assert.Equal("/", host.Services.GetService<Extensions.Hosting.IHostingEnvironment>().ContentRootPath);
}
}
@ -581,8 +583,13 @@ namespace Microsoft.AspNetCore.Hosting
.Build())
{
var basePath = host.Services.GetRequiredService<IHostingEnvironment>().ContentRootPath;
var basePath2 = host.Services.GetService<Extensions.Hosting.IHostingEnvironment>().ContentRootPath;
Assert.True(Path.IsPathRooted(basePath));
Assert.EndsWith(Path.DirectorySeparatorChar + "testroot", basePath);
Assert.True(Path.IsPathRooted(basePath2));
Assert.EndsWith(Path.DirectorySeparatorChar + "testroot", basePath2);
}
}
@ -596,6 +603,7 @@ namespace Microsoft.AspNetCore.Hosting
{
var appBase = AppContext.BaseDirectory;
Assert.Equal(appBase, host.Services.GetService<IHostingEnvironment>().ContentRootPath);
Assert.Equal(appBase, host.Services.GetService<Extensions.Hosting.IHostingEnvironment>().ContentRootPath);
}
}
@ -620,7 +628,9 @@ namespace Microsoft.AspNetCore.Hosting
.Build())
{
var hostingEnv = host.Services.GetService<IHostingEnvironment>();
var hostingEnv2 = host.Services.GetService<Extensions.Hosting.IHostingEnvironment>();
Assert.Equal(typeof(Startup).Assembly.GetName().Name, hostingEnv.ApplicationName);
Assert.Equal(typeof(Startup).Assembly.GetName().Name, hostingEnv2.ApplicationName);
}
}
@ -634,7 +644,9 @@ namespace Microsoft.AspNetCore.Hosting
.Build())
{
var hostingEnv = host.Services.GetService<IHostingEnvironment>();
var hostingEnv2 = host.Services.GetService<Extensions.Hosting.IHostingEnvironment>();
Assert.Equal(typeof(StartupNoServices).Assembly.GetName().Name, hostingEnv.ApplicationName);
Assert.Equal(typeof(StartupNoServices).Assembly.GetName().Name, hostingEnv2.ApplicationName);
}
}
@ -1046,7 +1058,7 @@ namespace Microsoft.AspNetCore.Hosting
.ConfigureServices(services => services.AddSingleton<ITestSink>(loggerProvider.Sink))
.ConfigureLogging((_, lf) => lf.AddProvider(loggerProvider))
.ConfigureAppConfiguration((context, configurationBuilder) => configurationBuilder.AddInMemoryCollection(
new []
new[]
{
new KeyValuePair<string,string>("testhostingstartup:config", "value")
}));

View File

@ -167,6 +167,7 @@ namespace Microsoft.AspNetCore.Hosting
.Build())
{
var lifetime = host.Services.GetRequiredService<IApplicationLifetime>();
var lifetime2 = host.Services.GetRequiredService<Extensions.Hosting.IApplicationLifetime>();
var server = (FakeServer)host.Services.GetRequiredService<IServer>();
var cts = new CancellationTokenSource();
@ -175,6 +176,7 @@ namespace Microsoft.AspNetCore.Hosting
// Wait on the host to be started
lifetime.ApplicationStarted.WaitHandle.WaitOne();
Assert.True(lifetime2.ApplicationStarted.IsCancellationRequested);
Assert.Equal(1, server.StartInstances.Count);
Assert.Equal(0, server.StartInstances[0].DisposeCalls);
@ -183,6 +185,7 @@ namespace Microsoft.AspNetCore.Hosting
// Wait on the host to shutdown
lifetime.ApplicationStopped.WaitHandle.WaitOne();
Assert.True(lifetime2.ApplicationStopped.IsCancellationRequested);
// Wait for RunAsync to finish to guarantee Disposal of WebHost
await runInBackground;
@ -408,11 +411,14 @@ namespace Microsoft.AspNetCore.Hosting
.Build())
{
var applicationLifetime = host.Services.GetService<IApplicationLifetime>();
var applicationLifetime2 = host.Services.GetService<Extensions.Hosting.IApplicationLifetime>();
Assert.False(applicationLifetime.ApplicationStarted.IsCancellationRequested);
Assert.False(applicationLifetime2.ApplicationStarted.IsCancellationRequested);
await host.StartAsync();
Assert.True(applicationLifetime.ApplicationStarted.IsCancellationRequested);
Assert.True(applicationLifetime2.ApplicationStarted.IsCancellationRequested);
}
}
@ -424,17 +430,26 @@ namespace Microsoft.AspNetCore.Hosting
.Build())
{
var applicationLifetime = host.Services.GetService<IApplicationLifetime>();
var applicationLifetime2 = host.Services.GetService<Extensions.Hosting.IApplicationLifetime>();
var started = RegisterCallbacksThatThrow(applicationLifetime.ApplicationStarted);
var stopping = RegisterCallbacksThatThrow(applicationLifetime.ApplicationStopping);
var stopped = RegisterCallbacksThatThrow(applicationLifetime.ApplicationStopped);
var started2 = RegisterCallbacksThatThrow(applicationLifetime2.ApplicationStarted);
var stopping2 = RegisterCallbacksThatThrow(applicationLifetime2.ApplicationStopping);
var stopped2 = RegisterCallbacksThatThrow(applicationLifetime2.ApplicationStopped);
await host.StartAsync();
Assert.True(applicationLifetime.ApplicationStarted.IsCancellationRequested);
Assert.True(applicationLifetime2.ApplicationStarted.IsCancellationRequested);
Assert.True(started.All(s => s));
Assert.True(started2.All(s => s));
host.Dispose();
Assert.True(stopping.All(s => s));
Assert.True(stopping2.All(s => s));
Assert.True(stopped.All(s => s));
Assert.True(stopped2.All(s => s));
}
}
@ -663,18 +678,24 @@ namespace Microsoft.AspNetCore.Hosting
.Build())
{
var applicationLifetime = host.Services.GetService<IApplicationLifetime>();
var applicationLifetime2 = host.Services.GetService<Extensions.Hosting.IApplicationLifetime>();
var started = RegisterCallbacksThatThrow(applicationLifetime.ApplicationStarted);
var stopping = RegisterCallbacksThatThrow(applicationLifetime.ApplicationStopping);
var started2 = RegisterCallbacksThatThrow(applicationLifetime2.ApplicationStarted);
var stopping2 = RegisterCallbacksThatThrow(applicationLifetime2.ApplicationStopping);
await host.StartAsync();
Assert.True(events1[0]);
Assert.True(events2[0]);
Assert.True(started.All(s => s));
Assert.True(started2.All(s => s));
host.Dispose();
Assert.True(events1[1]);
Assert.True(events2[1]);
Assert.True(stopping.All(s => s));
Assert.True(stopping2.All(s => s));
}
}
@ -689,7 +710,9 @@ namespace Microsoft.AspNetCore.Hosting
{
await host.StartAsync();
var env = host.Services.GetService<IHostingEnvironment>();
var env2 = host.Services.GetService<Extensions.Hosting.IHostingEnvironment>();
Assert.Equal("Changed", env.EnvironmentName);
Assert.Equal("Changed", env2.EnvironmentName);
}
}
@ -771,7 +794,9 @@ namespace Microsoft.AspNetCore.Hosting
using (var host = CreateBuilder().UseFakeServer().Build())
{
var env = host.Services.GetService<IHostingEnvironment>();
var env2 = host.Services.GetService<Extensions.Hosting.IHostingEnvironment>();
Assert.Equal(EnvironmentName.Production, env.EnvironmentName);
Assert.Equal(EnvironmentName.Production, env2.EnvironmentName);
}
}
@ -790,6 +815,8 @@ namespace Microsoft.AspNetCore.Hosting
using (var host = CreateBuilder(config).UseFakeServer().Build())
{
var env = host.Services.GetService<IHostingEnvironment>();
var env2 = host.Services.GetService<Extensions.Hosting.IHostingEnvironment>();
Assert.Equal(EnvironmentName.Staging, env.EnvironmentName);
Assert.Equal(EnvironmentName.Staging, env.EnvironmentName);
}
}
@ -990,7 +1017,7 @@ namespace Microsoft.AspNetCore.Hosting
{
private readonly IApplicationLifetime _lifetime;
public TestHostedService(IApplicationLifetime lifetime)
public TestHostedService(IApplicationLifetime lifetime, Extensions.Hosting.IApplicationLifetime lifetime2)
{
_lifetime = lifetime;
}