Remove IServerLoader and add the IServerFactory to the DI container

- This change removes the indirection and between the IServerLoader and
the IServerFactory. We now add the IServerFactory directly to the DI
container and resolve it from there.
- Moved logic that resolves IServerFactory from an assembly to a static
helper
This commit is contained in:
David Fowler 2016-03-29 22:40:42 -07:00
parent 8451d1afcb
commit 1182a5a9ca
11 changed files with 125 additions and 140 deletions

View File

@ -26,13 +26,6 @@ namespace Microsoft.AspNetCore.Hosting
/// <returns>The <see cref="IWebHostBuilder"/>.</returns> /// <returns>The <see cref="IWebHostBuilder"/>.</returns>
IWebHostBuilder UseLoggerFactory(ILoggerFactory loggerFactory); IWebHostBuilder UseLoggerFactory(ILoggerFactory loggerFactory);
/// <summary>
/// Specify the <see cref="IServerFactory"/> to be used by the web host.
/// </summary>
/// <param name="factory">The <see cref="IServerFactory"/> to be used.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
IWebHostBuilder UseServer(IServerFactory factory);
/// <summary> /// <summary>
/// Specify the startup type to be used by the web host. /// Specify the startup type to be used by the web host.
/// </summary> /// </summary>

View File

@ -0,0 +1,31 @@
using System;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Hosting.Server;
namespace Microsoft.AspNetCore.Hosting.Internal
{
internal static class ServerLoader
{
internal static Type ResolveServerFactoryType(string assemblyName)
{
var assembly = Assembly.Load(new AssemblyName(assemblyName));
if (assembly == null)
{
throw new InvalidOperationException(string.Format("The assembly {0} failed to load.", assemblyName));
}
var serverTypeInfo = assembly.DefinedTypes.Where(
t => t.ImplementedInterfaces.FirstOrDefault(interf => interf.Equals(typeof(IServerFactory))) != null)
.FirstOrDefault();
if (serverTypeInfo == null)
{
throw new InvalidOperationException($"No server type found that implements IServerFactory in assembly: {assemblyName}.");
}
return serverTypeInfo.AsType();
}
}
}

View File

@ -31,14 +31,16 @@ namespace Microsoft.AspNetCore.Hosting.Internal
private RequestDelegate _application; private RequestDelegate _application;
private ILogger<WebHost> _logger; private ILogger<WebHost> _logger;
// Used for testing only
internal WebHostOptions Options => _options;
// Only one of these should be set // Only one of these should be set
internal string StartupAssemblyName { get; set; } internal string StartupAssemblyName { get; set; }
internal StartupMethods Startup { get; set; } internal StartupMethods Startup { get; set; }
internal Type StartupType { get; set; } internal Type StartupType { get; set; }
// Only one of these should be set private IServerFactory ServerFactory { get; set; }
internal IServerFactory ServerFactory { get; set; }
internal string ServerFactoryLocation { get; set; }
private IServer Server { get; set; } private IServer Server { get; set; }
public WebHost( public WebHost(
@ -207,18 +209,9 @@ namespace Microsoft.AspNetCore.Hosting.Internal
{ {
if (Server == null) if (Server == null)
{ {
if (ServerFactory == null) ServerFactory = _applicationServices.GetRequiredService<IServerFactory>();
{
// Blow up if we don't have a server set at this point
if (ServerFactoryLocation == null)
{
throw new InvalidOperationException("IHostingBuilder.UseServer() is required for " + nameof(Start) + "()");
}
ServerFactory = _applicationServices.GetRequiredService<IServerLoader>().LoadServerFactory(ServerFactoryLocation);
}
Server = ServerFactory.CreateServer(_config); Server = ServerFactory.CreateServer(_config);
var addresses = Server.Features?.Get<IServerAddressesFeature>()?.Addresses; var addresses = Server.Features?.Get<IServerAddressesFeature>()?.Addresses;
if (addresses != null && !addresses.IsReadOnly && addresses.Count == 0) if (addresses != null && !addresses.IsReadOnly && addresses.Count == 0)
{ {

View File

@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
DetailedErrors = ParseBool(configuration, WebHostDefaults.DetailedErrorsKey); DetailedErrors = ParseBool(configuration, WebHostDefaults.DetailedErrorsKey);
CaptureStartupErrors = ParseBool(configuration, WebHostDefaults.CaptureStartupErrorsKey); CaptureStartupErrors = ParseBool(configuration, WebHostDefaults.CaptureStartupErrorsKey);
Environment = configuration[WebHostDefaults.EnvironmentKey]; Environment = configuration[WebHostDefaults.EnvironmentKey];
ServerFactoryLocation = configuration[WebHostDefaults.ServerKey]; ServerFactoryAssembly = configuration[WebHostDefaults.ServerKey];
WebRoot = configuration[WebHostDefaults.WebRootKey]; WebRoot = configuration[WebHostDefaults.WebRootKey];
ContentRootPath = configuration[WebHostDefaults.ContentRootKey]; ContentRootPath = configuration[WebHostDefaults.ContentRootKey];
} }
@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
public string Environment { get; set; } public string Environment { get; set; }
public string ServerFactoryLocation { get; set; } public string ServerFactoryAssembly { get; set; }
public string WebRoot { get; set; } public string WebRoot { get; set; }

View File

@ -1,10 +0,0 @@
// 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.
namespace Microsoft.AspNetCore.Hosting.Server
{
public interface IServerLoader
{
IServerFactory LoadServerFactory(string assemblyName);
}
}

View File

@ -1,50 +0,0 @@
// 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.
using System;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting.Server
{
public class ServerLoader : IServerLoader
{
private readonly IServiceProvider _services;
public ServerLoader(IServiceProvider services)
{
_services = services;
}
public IServerFactory LoadServerFactory(string assemblyName)
{
if (assemblyName == null)
{
throw new ArgumentNullException(nameof(assemblyName));
}
if (string.IsNullOrEmpty(assemblyName))
{
throw new ArgumentException(string.Empty, nameof(assemblyName));
}
var assembly = Assembly.Load(new AssemblyName(assemblyName));
if (assembly == null)
{
throw new Exception(string.Format("The assembly {0} failed to load.", assemblyName));
}
var serverTypeInfo = assembly.DefinedTypes.Where(
t => t.ImplementedInterfaces.FirstOrDefault(interf => interf.Equals(typeof(IServerFactory))) != null)
.FirstOrDefault();
if (serverTypeInfo == null)
{
throw new InvalidOperationException($"No server type found that implements IServerFactory in assembly: {assemblyName}.");
}
return (IServerFactory)ActivatorUtilities.GetServiceOrCreateInstance(_services, serverTypeInfo.AsType());
}
}
}

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting.Builder; using Microsoft.AspNetCore.Hosting.Builder;
@ -38,9 +39,6 @@ namespace Microsoft.AspNetCore.Hosting
private StartupMethods _startup; private StartupMethods _startup;
private Type _startupType; private Type _startupType;
// Only one of these should be set
private IServerFactory _serverFactory;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="WebHostBuilder"/> class. /// Initializes a new instance of the <see cref="WebHostBuilder"/> class.
/// </summary> /// </summary>
@ -89,22 +87,6 @@ namespace Microsoft.AspNetCore.Hosting
return this; return this;
} }
/// <summary>
/// Specify the <see cref="IServerFactory"/> to be used by the web host.
/// </summary>
/// <param name="factory">The <see cref="IServerFactory"/> to be used.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public IWebHostBuilder UseServer(IServerFactory factory)
{
if (factory == null)
{
throw new ArgumentNullException(nameof(factory));
}
_serverFactory = factory;
return this;
}
/// <summary> /// <summary>
/// Specify the startup type to be used by the web host. /// Specify the startup type to be used by the web host.
/// </summary> /// </summary>
@ -189,10 +171,6 @@ namespace Microsoft.AspNetCore.Hosting
var host = new WebHost(hostingServices, startupLoader, _options, _config); var host = new WebHost(hostingServices, startupLoader, _options, _config);
// Only one of these should be set, but they are used in priority
host.ServerFactory = _serverFactory;
host.ServerFactoryLocation = _options.ServerFactoryLocation;
// Only one of these should be set, but they are used in priority // Only one of these should be set, but they are used in priority
host.Startup = _startup; host.Startup = _startup;
host.StartupType = _startupType; host.StartupType = _startupType;
@ -227,8 +205,6 @@ namespace Microsoft.AspNetCore.Hosting
services.AddLogging(); services.AddLogging();
services.AddTransient<IStartupLoader, StartupLoader>(); services.AddTransient<IStartupLoader, StartupLoader>();
services.AddTransient<IServerLoader, ServerLoader>();
services.AddTransient<IApplicationBuilderFactory, ApplicationBuilderFactory>(); services.AddTransient<IApplicationBuilderFactory, ApplicationBuilderFactory>();
services.AddTransient<IHttpContextFactory, HttpContextFactory>(); services.AddTransient<IHttpContextFactory, HttpContextFactory>();
services.AddOptions(); services.AddOptions();
@ -248,6 +224,13 @@ namespace Microsoft.AspNetCore.Hosting
services.AddSingleton(defaultPlatformServices.Application); services.AddSingleton(defaultPlatformServices.Application);
services.AddSingleton(defaultPlatformServices.Runtime); services.AddSingleton(defaultPlatformServices.Runtime);
if (!string.IsNullOrEmpty(_options.ServerFactoryAssembly))
{
// Add the server factory
var serverFactoryType = ServerLoader.ResolveServerFactoryType(_options.ServerFactoryAssembly);
services.AddSingleton(typeof(IServerFactory), serverFactoryType);
}
foreach (var configureServices in _configureServicesDelegates) foreach (var configureServices in _configureServicesDelegates)
{ {
configureServices(services); configureServices(services);

View File

@ -2,9 +2,12 @@
// 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;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Hosting namespace Microsoft.AspNetCore.Hosting
{ {
@ -104,6 +107,27 @@ namespace Microsoft.AspNetCore.Hosting
return hostBuilder.UseSetting(WebHostDefaults.ServerKey, assemblyName); return hostBuilder.UseSetting(WebHostDefaults.ServerKey, assemblyName);
} }
/// <summary>
/// Specify the <see cref="IServerFactory"/> to be used by the web host.
/// </summary>
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="factory">The <see cref="IServerFactory"/> to be used.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseServer(this IWebHostBuilder hostBuilder, IServerFactory factory)
{
if (factory == null)
{
throw new ArgumentNullException(nameof(factory));
}
return hostBuilder.ConfigureServices(services =>
{
// It would be nicer if this was transient but we need to pass in the
// factory instance directly
services.AddSingleton(factory);
});
}
/// <summary> /// <summary>
/// Specify the server to be used by the web host. /// Specify the server to be used by the web host.
/// </summary> /// </summary>
@ -117,6 +141,8 @@ namespace Microsoft.AspNetCore.Hosting
throw new ArgumentNullException(nameof(server)); throw new ArgumentNullException(nameof(server));
} }
// It would be nicer if this was transient but we need to pass in the
// server instance directly
return hostBuilder.UseServer(new ServerFactory(server)); return hostBuilder.UseServer(new ServerFactory(server));
} }

View File

@ -242,14 +242,14 @@ namespace Microsoft.AspNetCore.Hosting
public void CodeBasedSettingsCodeBasedOverride() public void CodeBasedSettingsCodeBasedOverride()
{ {
var hostBuilder = new WebHostBuilder() var hostBuilder = new WebHostBuilder()
.UseSetting(WebHostDefaults.ServerKey, "ServerA") .UseSetting(WebHostDefaults.EnvironmentKey, "EnvA")
.UseSetting(WebHostDefaults.ServerKey, "ServerB") .UseSetting(WebHostDefaults.EnvironmentKey, "EnvB")
.UseServer(new TestServer()) .UseServer(new TestServer())
.UseStartup<StartupNoServices>(); .UseStartup<StartupNoServices>();
var host = (WebHost)hostBuilder.Build(); var host = (WebHost)hostBuilder.Build();
Assert.Equal("ServerB", host.ServerFactoryLocation); Assert.Equal("EnvB", host.Options.Environment);
} }
[Fact] [Fact]
@ -257,7 +257,7 @@ namespace Microsoft.AspNetCore.Hosting
{ {
var settings = new Dictionary<string, string> var settings = new Dictionary<string, string>
{ {
{ WebHostDefaults.ServerKey, "ServerB" } { WebHostDefaults.EnvironmentKey, "EnvB" }
}; };
var config = new ConfigurationBuilder() var config = new ConfigurationBuilder()
@ -265,14 +265,14 @@ namespace Microsoft.AspNetCore.Hosting
.Build(); .Build();
var hostBuilder = new WebHostBuilder() var hostBuilder = new WebHostBuilder()
.UseSetting(WebHostDefaults.ServerKey, "ServerA") .UseSetting(WebHostDefaults.EnvironmentKey, "EnvA")
.UseConfiguration(config) .UseConfiguration(config)
.UseServer(new TestServer()) .UseServer(new TestServer())
.UseStartup<StartupNoServices>(); .UseStartup<StartupNoServices>();
var host = (WebHost)hostBuilder.Build(); var host = (WebHost)hostBuilder.Build();
Assert.Equal("ServerB", host.ServerFactoryLocation); Assert.Equal("EnvB", host.Options.Environment);
} }
[Fact] [Fact]
@ -280,7 +280,7 @@ namespace Microsoft.AspNetCore.Hosting
{ {
var settings = new Dictionary<string, string> var settings = new Dictionary<string, string>
{ {
{ WebHostDefaults.ServerKey, "ServerA" } { WebHostDefaults.EnvironmentKey, "EnvA" }
}; };
var config = new ConfigurationBuilder() var config = new ConfigurationBuilder()
@ -289,13 +289,13 @@ namespace Microsoft.AspNetCore.Hosting
var hostBuilder = new WebHostBuilder() var hostBuilder = new WebHostBuilder()
.UseConfiguration(config) .UseConfiguration(config)
.UseSetting(WebHostDefaults.ServerKey, "ServerB") .UseSetting(WebHostDefaults.EnvironmentKey, "EnvB")
.UseServer(new TestServer()) .UseServer(new TestServer())
.UseStartup<StartupNoServices>(); .UseStartup<StartupNoServices>();
var host = (WebHost)hostBuilder.Build(); var host = (WebHost)hostBuilder.Build();
Assert.Equal("ServerB", host.ServerFactoryLocation); Assert.Equal("EnvB", host.Options.Environment);
} }
[Fact] [Fact]
@ -303,7 +303,7 @@ namespace Microsoft.AspNetCore.Hosting
{ {
var settings = new Dictionary<string, string> var settings = new Dictionary<string, string>
{ {
{ WebHostDefaults.ServerKey, "ServerA" } { WebHostDefaults.EnvironmentKey, "EnvA" }
}; };
var config = new ConfigurationBuilder() var config = new ConfigurationBuilder()
@ -312,7 +312,7 @@ namespace Microsoft.AspNetCore.Hosting
var overrideSettings = new Dictionary<string, string> var overrideSettings = new Dictionary<string, string>
{ {
{ WebHostDefaults.ServerKey, "ServerB" } { WebHostDefaults.EnvironmentKey, "EnvB" }
}; };
var overrideConfig = new ConfigurationBuilder() var overrideConfig = new ConfigurationBuilder()
@ -327,7 +327,7 @@ namespace Microsoft.AspNetCore.Hosting
var host = (WebHost)hostBuilder.Build(); var host = (WebHost)hostBuilder.Build();
Assert.Equal("ServerB", host.ServerFactoryLocation); Assert.Equal("EnvB", host.Options.Environment);
} }
[Fact] [Fact]

View File

@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Hosting.Tests
var config = new WebHostOptions(new ConfigurationBuilder().AddInMemoryCollection(parameters).Build()); var config = new WebHostOptions(new ConfigurationBuilder().AddInMemoryCollection(parameters).Build());
Assert.Equal("wwwroot", config.WebRoot); Assert.Equal("wwwroot", config.WebRoot);
Assert.Equal("Microsoft.AspNetCore.Server.Kestrel", config.ServerFactoryLocation); Assert.Equal("Microsoft.AspNetCore.Server.Kestrel", config.ServerFactoryAssembly);
Assert.Equal("MyProjectReference", config.Application); Assert.Equal("MyProjectReference", config.Application);
Assert.Equal("Development", config.Environment); Assert.Equal("Development", config.Environment);
Assert.True(config.CaptureStartupErrors); Assert.True(config.CaptureStartupErrors);

View File

@ -24,7 +24,7 @@ using Xunit;
namespace Microsoft.AspNetCore.Hosting namespace Microsoft.AspNetCore.Hosting
{ {
public class WebHostTests : IServerFactory, IServer public class WebHostTests : IServerFactory
{ {
private readonly IList<StartInstance> _startInstances = new List<StartInstance>(); private readonly IList<StartInstance> _startInstances = new List<StartInstance>();
private IFeatureCollection _featuresSupportedByThisHost = NewFeatureCollection(); private IFeatureCollection _featuresSupportedByThisHost = NewFeatureCollection();
@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.Hosting
public void WebHostThrowsWithNoServer() public void WebHostThrowsWithNoServer()
{ {
var ex = Assert.Throws<InvalidOperationException>(() => CreateBuilder().Build().Start()); var ex = Assert.Throws<InvalidOperationException>(() => CreateBuilder().Build().Start());
Assert.True(ex.Message.Contains("UseServer()")); Assert.Equal("No service for type 'Microsoft.AspNetCore.Hosting.Server.IServerFactory' has been registered.", ex.Message);
} }
[Fact] [Fact]
@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Hosting
} }
[Fact] [Fact]
public void CanDefaultAddresseIfNotConfigured() public void CanDefaultAddressesIfNotConfigured()
{ {
var vals = new Dictionary<string, string> var vals = new Dictionary<string, string>
{ {
@ -128,7 +128,7 @@ namespace Microsoft.AspNetCore.Hosting
public void WebHostCanBeStarted() public void WebHostCanBeStarted()
{ {
var host = CreateBuilder() var host = CreateBuilder()
.UseServer((IServerFactory)this) .UseServer(this)
.UseStartup("Microsoft.AspNetCore.Hosting.Tests") .UseStartup("Microsoft.AspNetCore.Hosting.Tests")
.Start(); .Start();
@ -145,7 +145,7 @@ namespace Microsoft.AspNetCore.Hosting
public void WebHostShutsDownWhenTokenTriggers() public void WebHostShutsDownWhenTokenTriggers()
{ {
var host = CreateBuilder() var host = CreateBuilder()
.UseServer((IServerFactory)this) .UseServer(this)
.UseStartup("Microsoft.AspNetCore.Hosting.Tests") .UseStartup("Microsoft.AspNetCore.Hosting.Tests")
.Build(); .Build();
@ -173,7 +173,7 @@ namespace Microsoft.AspNetCore.Hosting
public void WebHostDisposesServiceProvider() public void WebHostDisposesServiceProvider()
{ {
var host = CreateBuilder() var host = CreateBuilder()
.UseServer((IServerFactory)this) .UseServer(this)
.ConfigureServices(s => .ConfigureServices(s =>
{ {
s.AddTransient<IFakeService, FakeService>(); s.AddTransient<IFakeService, FakeService>();
@ -200,7 +200,7 @@ namespace Microsoft.AspNetCore.Hosting
public void WebHostNotifiesApplicationStarted() public void WebHostNotifiesApplicationStarted()
{ {
var host = CreateBuilder() var host = CreateBuilder()
.UseServer((IServerFactory)this) .UseServer(this)
.Build(); .Build();
var applicationLifetime = host.Services.GetService<IApplicationLifetime>(); var applicationLifetime = host.Services.GetService<IApplicationLifetime>();
@ -216,7 +216,7 @@ namespace Microsoft.AspNetCore.Hosting
public void WebHostInjectsHostingEnvironment() public void WebHostInjectsHostingEnvironment()
{ {
var host = CreateBuilder() var host = CreateBuilder()
.UseServer((IServerFactory)this) .UseServer(this)
.UseStartup("Microsoft.AspNetCore.Hosting.Tests") .UseStartup("Microsoft.AspNetCore.Hosting.Tests")
.UseEnvironment("WithHostingEnvironment") .UseEnvironment("WithHostingEnvironment")
.Build(); .Build();
@ -237,7 +237,7 @@ namespace Microsoft.AspNetCore.Hosting
{ {
services.AddTransient<IStartupLoader, TestLoader>(); services.AddTransient<IStartupLoader, TestLoader>();
}) })
.UseServer((IServerFactory)this) .UseServer(this)
.UseStartup("Microsoft.AspNetCore.Hosting.Tests"); .UseStartup("Microsoft.AspNetCore.Hosting.Tests");
Assert.Throws<NotImplementedException>(() => builder.Build()); Assert.Throws<NotImplementedException>(() => builder.Build());
@ -246,7 +246,7 @@ namespace Microsoft.AspNetCore.Hosting
[Fact] [Fact]
public void CanCreateApplicationServicesWithAddedServices() public void CanCreateApplicationServicesWithAddedServices()
{ {
var host = CreateBuilder().UseServer((IServerFactory)this).ConfigureServices(services => services.AddOptions()).Build(); var host = CreateBuilder().UseServer(this).ConfigureServices(services => services.AddOptions()).Build();
Assert.NotNull(host.Services.GetRequiredService<IOptions<object>>()); Assert.NotNull(host.Services.GetRequiredService<IOptions<object>>());
} }
@ -256,7 +256,7 @@ namespace Microsoft.AspNetCore.Hosting
// Verify ordering // Verify ordering
var configureOrder = 0; var configureOrder = 0;
var host = CreateBuilder() var host = CreateBuilder()
.UseServer((IServerFactory)this) .UseServer(this)
.ConfigureServices(services => .ConfigureServices(services =>
{ {
services.AddTransient<IStartupFilter>(serviceProvider => new TestFilter( services.AddTransient<IStartupFilter>(serviceProvider => new TestFilter(
@ -300,7 +300,7 @@ namespace Microsoft.AspNetCore.Hosting
[Fact] [Fact]
public void EnvDefaultsToProductionIfNoConfig() public void EnvDefaultsToProductionIfNoConfig()
{ {
var host = CreateBuilder().UseServer((IServerFactory)this).Build(); var host = CreateBuilder().UseServer(this).Build();
var env = host.Services.GetService<IHostingEnvironment>(); var env = host.Services.GetService<IHostingEnvironment>();
Assert.Equal(EnvironmentName.Production, env.EnvironmentName); Assert.Equal(EnvironmentName.Production, env.EnvironmentName);
} }
@ -317,7 +317,7 @@ namespace Microsoft.AspNetCore.Hosting
.AddInMemoryCollection(vals); .AddInMemoryCollection(vals);
var config = builder.Build(); var config = builder.Build();
var host = CreateBuilder(config).UseServer((IServerFactory)this).Build(); var host = CreateBuilder(config).UseServer(this).Build();
var env = host.Services.GetService<IHostingEnvironment>(); var env = host.Services.GetService<IHostingEnvironment>();
Assert.Equal("Staging", env.EnvironmentName); Assert.Equal("Staging", env.EnvironmentName);
} }
@ -334,7 +334,7 @@ namespace Microsoft.AspNetCore.Hosting
.AddInMemoryCollection(vals); .AddInMemoryCollection(vals);
var config = builder.Build(); var config = builder.Build();
var host = CreateBuilder(config).UseServer((IServerFactory)this).Build(); var host = CreateBuilder(config).UseServer(this).Build();
var env = host.Services.GetService<IHostingEnvironment>(); var env = host.Services.GetService<IHostingEnvironment>();
Assert.Equal(Path.GetFullPath("testroot"), env.WebRootPath); Assert.Equal(Path.GetFullPath("testroot"), env.WebRootPath);
Assert.True(env.WebRootFileProvider.GetFileInfo("TextFile.txt").Exists); Assert.True(env.WebRootFileProvider.GetFileInfo("TextFile.txt").Exists);
@ -343,7 +343,7 @@ namespace Microsoft.AspNetCore.Hosting
[Fact] [Fact]
public void IsEnvironment_Extension_Is_Case_Insensitive() public void IsEnvironment_Extension_Is_Case_Insensitive()
{ {
var host = CreateBuilder().UseServer((IServerFactory)this).Build(); var host = CreateBuilder().UseServer(this).Build();
using (host) using (host)
{ {
host.Start(); host.Start();
@ -401,7 +401,7 @@ namespace Microsoft.AspNetCore.Hosting
public void WebHost_InvokesConfigureMethodsOnlyOnce() public void WebHost_InvokesConfigureMethodsOnlyOnce()
{ {
var host = CreateBuilder() var host = CreateBuilder()
.UseServer((IServerFactory)this) .UseServer(this)
.UseStartup<CountStartup>() .UseStartup<CountStartup>()
.Build(); .Build();
using (host) using (host)
@ -434,7 +434,7 @@ namespace Microsoft.AspNetCore.Hosting
public void WebHost_ThrowsForBadConfigureServiceSignature() public void WebHost_ThrowsForBadConfigureServiceSignature()
{ {
var builder = CreateBuilder() var builder = CreateBuilder()
.UseServer((IServerFactory)this) .UseServer(this)
.UseStartup<BadConfigureServicesStartup>(); .UseStartup<BadConfigureServicesStartup>();
var ex = Assert.Throws<InvalidOperationException>(() => builder.Build()); var ex = Assert.Throws<InvalidOperationException>(() => builder.Build());
@ -450,7 +450,7 @@ namespace Microsoft.AspNetCore.Hosting
private IWebHost CreateHost(RequestDelegate requestDelegate) private IWebHost CreateHost(RequestDelegate requestDelegate)
{ {
var builder = CreateBuilder() var builder = CreateBuilder()
.UseServer((IServerFactory)this) .UseServer(this)
.Configure( .Configure(
appBuilder => appBuilder =>
{ {
@ -497,7 +497,7 @@ namespace Microsoft.AspNetCore.Hosting
{ {
_instanceFeaturesSupportedByThisHost = new FeatureCollection(); _instanceFeaturesSupportedByThisHost = new FeatureCollection();
_instanceFeaturesSupportedByThisHost.Set<IServerAddressesFeature>(new ServerAddressesFeature()); _instanceFeaturesSupportedByThisHost.Set<IServerAddressesFeature>(new ServerAddressesFeature());
return this; return new FakeServer(this);
} }
private class StartInstance : IDisposable private class StartInstance : IDisposable
@ -671,5 +671,24 @@ namespace Microsoft.AspNetCore.Hosting
{ {
public string TraceIdentifier { get; set; } public string TraceIdentifier { get; set; }
} }
private class FakeServer : IServer
{
private readonly WebHostTests _webHostTests;
public FakeServer(WebHostTests webHostTests)
{
_webHostTests = webHostTests;
}
public IFeatureCollection Features => _webHostTests.Features;
public void Dispose() => _webHostTests.Dispose();
public void Start<TContext>(IHttpApplication<TContext> application)
{
_webHostTests.Start<TContext>(application);
}
}
} }
} }