// 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.Diagnostics; using System.Runtime.Versioning; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting.Builder; using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Startup; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Internal; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.PlatformAbstractions; namespace Microsoft.AspNetCore.Hosting { /// /// A builder for /// public class WebHostBuilder : IWebHostBuilder { private readonly IHostingEnvironment _hostingEnvironment; private readonly ILoggerFactory _loggerFactory; private IConfiguration _config = new ConfigurationBuilder().AddInMemoryCollection().Build(); private WebHostOptions _options; private Action _configureServices; // Only one of these should be set private StartupMethods _startup; private Type _startupType; // Only one of these should be set private IServerFactory _serverFactory; public WebHostBuilder() { _hostingEnvironment = new HostingEnvironment(); _loggerFactory = new LoggerFactory(); } /// /// Add or replace a setting in . /// /// The key of the setting to add or replace. /// The value of the setting to add or replace. /// The . public IWebHostBuilder UseSetting(string key, string value) { _config[key] = value; return this; } /// /// Get the setting value from the configuration. /// /// The key of the setting to look up. /// The value the setting currently contains. public string GetSetting(string key) { return _config[key]; } /// /// Specify the to be used by the web host. /// /// The to be used. /// The . public IWebHostBuilder UseServer(IServerFactory factory) { if (factory == null) { throw new ArgumentNullException(nameof(factory)); } _serverFactory = factory; return this; } /// /// Specify the startup type to be used by the web host. /// /// The to be used. /// The . public IWebHostBuilder UseStartup(Type startupType) { if (startupType == null) { throw new ArgumentNullException(nameof(startupType)); } _startupType = startupType; return this; } /// /// Specify the delegate that is used to configure the services of the web application. /// /// The delegate that configures the . /// The . public IWebHostBuilder ConfigureServices(Action configureServices) { _configureServices = configureServices; return this; } /// /// Specify the startup method to be used to configure the web application. /// /// The delegate that configures the . /// The . public IWebHostBuilder Configure(Action configureApp) { if (configureApp == null) { throw new ArgumentNullException(nameof(configureApp)); } _startup = new StartupMethods(configureApp); return this; } /// /// Configure the provided which will be available as a hosting service. /// /// The delegate that configures the . /// The . public IWebHostBuilder ConfigureLogging(Action configureLogging) { configureLogging(_loggerFactory); return this; } /// /// Builds the required services and an which hosts a web application. /// public IWebHost Build() { var hostingServices = BuildHostingServices(); var hostingContainer = hostingServices.BuildServiceProvider(); var appEnvironment = hostingContainer.GetRequiredService(); var startupLoader = hostingContainer.GetRequiredService(); // Initialize the hosting environment _hostingEnvironment.Initialize(appEnvironment.ApplicationBasePath, _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 host.Startup = _startup; host.StartupType = _startupType; host.StartupAssemblyName = _options.Application; host.Initialize(); return host; } private IServiceCollection BuildHostingServices() { _options = new WebHostOptions(_config); var services = new ServiceCollection(); services.AddSingleton(_hostingEnvironment); services.AddSingleton(_loggerFactory); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddLogging(); services.AddOptions(); var diagnosticSource = new DiagnosticListener("Microsoft.AspNetCore"); services.AddSingleton(diagnosticSource); services.AddSingleton(diagnosticSource); // Conjure up a RequestServices services.AddTransient(); var defaultPlatformServices = PlatformServices.Default; if (defaultPlatformServices != null) { if (defaultPlatformServices.Application != null) { var appEnv = defaultPlatformServices.Application; if (!string.IsNullOrEmpty(_options.ApplicationBasePath)) { appEnv = new WrappedApplicationEnvironment(_options.ApplicationBasePath, appEnv); } services.TryAddSingleton(appEnv); } if (defaultPlatformServices.Runtime != null) { services.TryAddSingleton(defaultPlatformServices.Runtime); } } if (_configureServices != null) { _configureServices(services); } return services; } private class WrappedApplicationEnvironment : IApplicationEnvironment { public WrappedApplicationEnvironment(string applicationBasePath, IApplicationEnvironment env) { ApplicationBasePath = applicationBasePath; ApplicationName = env.ApplicationName; ApplicationVersion = env.ApplicationVersion; RuntimeFramework = env.RuntimeFramework; } public string ApplicationBasePath { get; } public string ApplicationName { get; } public string ApplicationVersion { get; } public FrameworkName RuntimeFramework { get; } } } }