diff --git a/src/Microsoft.AspNetCore.Hosting.Server.Abstractions/IServerAddressesFeature.cs b/src/Microsoft.AspNetCore.Hosting.Server.Abstractions/Features/IServerAddressesFeature.cs similarity index 84% rename from src/Microsoft.AspNetCore.Hosting.Server.Abstractions/IServerAddressesFeature.cs rename to src/Microsoft.AspNetCore.Hosting.Server.Abstractions/Features/IServerAddressesFeature.cs index 5a464cb75c..7c781b8485 100644 --- a/src/Microsoft.AspNetCore.Hosting.Server.Abstractions/IServerAddressesFeature.cs +++ b/src/Microsoft.AspNetCore.Hosting.Server.Abstractions/Features/IServerAddressesFeature.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; -namespace Microsoft.AspNetCore.Server.Features +namespace Microsoft.AspNetCore.Hosting.Server.Features { public interface IServerAddressesFeature { diff --git a/src/Microsoft.AspNetCore.Hosting.Server.Abstractions/IServerFactory.cs b/src/Microsoft.AspNetCore.Hosting.Server.Abstractions/IServerFactory.cs deleted file mode 100644 index 1f28b5bacf..0000000000 --- a/src/Microsoft.AspNetCore.Hosting.Server.Abstractions/IServerFactory.cs +++ /dev/null @@ -1,20 +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 Microsoft.Extensions.Configuration; - -namespace Microsoft.AspNetCore.Hosting.Server -{ - /// - /// Represents a factory for creating servers. - /// - public interface IServerFactory - { - /// - /// Creates based on the given configuration. - /// - /// An instance of . - /// The created server. - IServer CreateServer(IConfiguration configuration); - } -} diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/ServerLoader.cs b/src/Microsoft.AspNetCore.Hosting/Internal/ServerLoader.cs index 20f821932f..afdd820cb0 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/ServerLoader.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/ServerLoader.cs @@ -7,7 +7,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal { internal static class ServerLoader { - internal static Type ResolveServerFactoryType(string assemblyName) + internal static Type ResolveServerType(string assemblyName) { var assembly = Assembly.Load(new AssemblyName(assemblyName)); if (assembly == null) @@ -16,12 +16,12 @@ namespace Microsoft.AspNetCore.Hosting.Internal } var serverTypeInfo = assembly.DefinedTypes.Where( - t => t.ImplementedInterfaces.FirstOrDefault(interf => interf.Equals(typeof(IServerFactory))) != null) + t => t.ImplementedInterfaces.FirstOrDefault(interf => interf.Equals(typeof(IServer))) != null) .FirstOrDefault(); if (serverTypeInfo == null) { - throw new InvalidOperationException($"No server type found that implements IServerFactory in assembly: {assemblyName}."); + throw new InvalidOperationException($"No server type found that implements IServer in assembly: {assemblyName}."); } return serverTypeInfo.AsType(); diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs b/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs index 302cc18a80..54745fb505 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs @@ -8,10 +8,10 @@ using System.Linq; using System.Threading; using Microsoft.AspNetCore.Hosting.Builder; using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.AspNetCore.Hosting.Startup; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; -using Microsoft.AspNetCore.Server.Features; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -39,8 +39,6 @@ namespace Microsoft.AspNetCore.Hosting.Internal internal StartupMethods Startup { get; set; } internal Type StartupType { get; set; } - private IServerFactory ServerFactory { get; set; } - private IServer Server { get; set; } public WebHost( @@ -209,14 +207,25 @@ namespace Microsoft.AspNetCore.Hosting.Internal { if (Server == null) { - ServerFactory = _applicationServices.GetRequiredService(); - Server = ServerFactory.CreateServer(_config); + Server = _applicationServices.GetRequiredService(); var addresses = Server.Features?.Get()?.Addresses; if (addresses != null && !addresses.IsReadOnly && addresses.Count == 0) { - // Provide a default address if there aren't any configured. - addresses.Add("http://localhost:5000"); + var urls = _config[WebHostDefaults.ServerUrlsKey]; + if (!string.IsNullOrEmpty(urls)) + { + foreach (var value in urls.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) + { + addresses.Add(value); + } + } + + if (addresses.Count == 0) + { + // Provide a default address if there aren't any configured. + addresses.Add("http://localhost:5000"); + } } } } diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/WebHostOptions.cs b/src/Microsoft.AspNetCore.Hosting/Internal/WebHostOptions.cs index a57db8cbe1..500353a834 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/WebHostOptions.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/WebHostOptions.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal DetailedErrors = ParseBool(configuration, WebHostDefaults.DetailedErrorsKey); CaptureStartupErrors = ParseBool(configuration, WebHostDefaults.CaptureStartupErrorsKey); Environment = configuration[WebHostDefaults.EnvironmentKey]; - ServerFactoryAssembly = configuration[WebHostDefaults.ServerKey]; + ServerAssembly = configuration[WebHostDefaults.ServerKey]; WebRoot = configuration[WebHostDefaults.WebRootKey]; ContentRootPath = configuration[WebHostDefaults.ContentRootKey]; } @@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal public string Environment { get; set; } - public string ServerFactoryAssembly { get; set; } + public string ServerAssembly { get; set; } public string WebRoot { get; set; } diff --git a/src/Microsoft.AspNetCore.Hosting/Server/Features/ServerAddressesFeature.cs b/src/Microsoft.AspNetCore.Hosting/Server/Features/ServerAddressesFeature.cs new file mode 100644 index 0000000000..4f8e1bdb3d --- /dev/null +++ b/src/Microsoft.AspNetCore.Hosting/Server/Features/ServerAddressesFeature.cs @@ -0,0 +1,12 @@ +// 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.Collections.Generic; + +namespace Microsoft.AspNetCore.Hosting.Server.Features +{ + public class ServerAddressesFeature : IServerAddressesFeature + { + public ICollection Addresses { get; } = new List(); + } +} diff --git a/src/Microsoft.AspNetCore.Hosting/WebHostBuilder.cs b/src/Microsoft.AspNetCore.Hosting/WebHostBuilder.cs index 416df78198..af33553886 100644 --- a/src/Microsoft.AspNetCore.Hosting/WebHostBuilder.cs +++ b/src/Microsoft.AspNetCore.Hosting/WebHostBuilder.cs @@ -222,11 +222,11 @@ namespace Microsoft.AspNetCore.Hosting services.AddSingleton(defaultPlatformServices.Application); services.AddSingleton(defaultPlatformServices.Runtime); - if (!string.IsNullOrEmpty(_options.ServerFactoryAssembly)) + if (!string.IsNullOrEmpty(_options.ServerAssembly)) { - // Add the server factory - var serverFactoryType = ServerLoader.ResolveServerFactoryType(_options.ServerFactoryAssembly); - services.AddSingleton(typeof(IServerFactory), serverFactoryType); + // Add the server + var serverType = ServerLoader.ResolveServerType(_options.ServerAssembly); + services.AddSingleton(typeof(IServer), serverType); } foreach (var configureServices in _configureServicesDelegates) diff --git a/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs b/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs index ce32436203..f578499ef2 100644 --- a/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs @@ -107,27 +107,6 @@ namespace Microsoft.AspNetCore.Hosting return hostBuilder.UseSetting(WebHostDefaults.ServerKey, assemblyName); } - /// - /// Specify the to be used by the web host. - /// - /// The to configure. - /// The to be used. - /// The . - 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); - }); - } - /// /// Specify the server to be used by the web host. /// @@ -141,9 +120,12 @@ namespace Microsoft.AspNetCore.Hosting 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.ConfigureServices(services => + { + // It would be nicer if this was transient but we need to pass in the + // factory instance directly + services.AddSingleton(server); + }); } /// @@ -222,17 +204,5 @@ namespace Microsoft.AspNetCore.Hosting host.Start(); return host; } - - private class ServerFactory : IServerFactory - { - private readonly IServer _server; - - public ServerFactory(IServer server) - { - _server = server; - } - - public IServer CreateServer(IConfiguration configuration) => _server; - } } } diff --git a/src/Microsoft.AspNetCore.Hosting/WebHostExtensions.cs b/src/Microsoft.AspNetCore.Hosting/WebHostExtensions.cs index d959b8042f..4c2d815010 100644 --- a/src/Microsoft.AspNetCore.Hosting/WebHostExtensions.cs +++ b/src/Microsoft.AspNetCore.Hosting/WebHostExtensions.cs @@ -3,7 +3,7 @@ using System; using System.Threading; -using Microsoft.AspNetCore.Server.Features; +using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Hosting diff --git a/test/Microsoft.AspNetCore.Hosting.Tests/WebHostConfigurationsTests.cs b/test/Microsoft.AspNetCore.Hosting.Tests/WebHostConfigurationsTests.cs index c7ffe999d4..3facd52dc3 100644 --- a/test/Microsoft.AspNetCore.Hosting.Tests/WebHostConfigurationsTests.cs +++ b/test/Microsoft.AspNetCore.Hosting.Tests/WebHostConfigurationsTests.cs @@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Hosting.Tests var config = new WebHostOptions(new ConfigurationBuilder().AddInMemoryCollection(parameters).Build()); Assert.Equal("wwwroot", config.WebRoot); - Assert.Equal("Microsoft.AspNetCore.Server.Kestrel", config.ServerFactoryAssembly); + Assert.Equal("Microsoft.AspNetCore.Server.Kestrel", config.ServerAssembly); Assert.Equal("MyProjectReference", config.Application); Assert.Equal("Development", config.Environment); Assert.True(config.CaptureStartupErrors); diff --git a/test/Microsoft.AspNetCore.Hosting.Tests/WebHostTests.cs b/test/Microsoft.AspNetCore.Hosting.Tests/WebHostTests.cs index 3b4c5d47a1..40ce1c9ed2 100644 --- a/test/Microsoft.AspNetCore.Hosting.Tests/WebHostTests.cs +++ b/test/Microsoft.AspNetCore.Hosting.Tests/WebHostTests.cs @@ -10,11 +10,12 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting.Fakes; +using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.AspNetCore.Hosting.Startup; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; -using Microsoft.AspNetCore.Server.Features; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -24,11 +25,10 @@ using Xunit; namespace Microsoft.AspNetCore.Hosting { - public class WebHostTests : IServerFactory + public class WebHostTests : IServer { private readonly IList _startInstances = new List(); private IFeatureCollection _featuresSupportedByThisHost = NewFeatureCollection(); - private IFeatureCollection _instanceFeaturesSupportedByThisHost; public IFeatureCollection Features { @@ -41,14 +41,6 @@ namespace Microsoft.AspNetCore.Hosting features[feature.Key] = feature.Value; } - if (_instanceFeaturesSupportedByThisHost != null) - { - foreach (var feature in _instanceFeaturesSupportedByThisHost) - { - features[feature.Key] = feature.Value; - } - } - return features; } } @@ -57,8 +49,9 @@ namespace Microsoft.AspNetCore.Hosting { var stub = new StubFeatures(); var features = new FeatureCollection(); - features[typeof(IHttpRequestFeature)] = stub; - features[typeof(IHttpResponseFeature)] = stub; + features.Set(stub); + features.Set(stub); + features.Set(new ServerAddressesFeature()); return features; } @@ -66,7 +59,7 @@ namespace Microsoft.AspNetCore.Hosting public void WebHostThrowsWithNoServer() { var ex = Assert.Throws(() => CreateBuilder().Build().Start()); - Assert.Equal("No service for type 'Microsoft.AspNetCore.Hosting.Server.IServerFactory' has been registered.", ex.Message); + Assert.Equal("No service for type 'Microsoft.AspNetCore.Hosting.Server.IServer' has been registered.", ex.Message); } [Fact] @@ -138,7 +131,7 @@ namespace Microsoft.AspNetCore.Hosting host.Dispose(); - Assert.Equal(1, _startInstances[0].DisposeCalls); + Assert.Equal(2, _startInstances[0].DisposeCalls); // Once as the server, once from the DI Container } [Fact] @@ -166,7 +159,7 @@ namespace Microsoft.AspNetCore.Hosting // Wait on the host to shutdown lifetime.ApplicationStopped.WaitHandle.WaitOne(); - Assert.Equal(1, _startInstances[0].DisposeCalls); + Assert.Equal(2, _startInstances[0].DisposeCalls); // Once as the server, once from the DI Container } [Fact] @@ -493,13 +486,6 @@ namespace Microsoft.AspNetCore.Hosting } } - public IServer CreateServer(IConfiguration configuration) - { - _instanceFeaturesSupportedByThisHost = new FeatureCollection(); - _instanceFeaturesSupportedByThisHost.Set(new ServerAddressesFeature()); - return new FakeServer(this); - } - private class StartInstance : IDisposable { public int DisposeCalls { get; set; } @@ -566,11 +552,6 @@ namespace Microsoft.AspNetCore.Hosting } } - private class ServerAddressesFeature : IServerAddressesFeature - { - public ICollection Addresses { get; } = new List(); - } - private class AllMessagesAreNeeded : ILoggerProvider, ILogger { public bool IsEnabled(LogLevel logLevel) => true; @@ -671,24 +652,5 @@ namespace Microsoft.AspNetCore.Hosting { 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(IHttpApplication application) - { - _webHostTests.Start(application); - } - } } }