// 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; }
}
}
}