Additional fiels in HostingEnvironment and Renames

- Added ApplicationName, ContentRootPath and ContentRootFileProvider
- Removed Configuration
- Removed MapPath
This commit is contained in:
John Luo 2016-03-10 16:17:14 -08:00
parent 9ade9da2f7
commit 5ac589317f
13 changed files with 109 additions and 209 deletions

View File

@ -15,7 +15,7 @@ namespace SampleStartups
{
var host = new WebHostBuilder()
.UseServer("Microsoft.AspNetCore.Server.Kestrel") // Set the server manually
.UseApplicationBasePath(Directory.GetCurrentDirectory()) // Override the application base with the current directory
.UseContentRoot(Directory.GetCurrentDirectory()) // Override the content root with the current directory
.UseUrls("http://*:1000", "https://*:902")
.UseEnvironment("Development")
.UseWebRoot("public")

View File

@ -76,33 +76,5 @@ namespace Microsoft.AspNetCore.Hosting
environmentName,
StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Determines the physical path corresponding to the given virtual path.
/// </summary>
/// <param name="hostingEnvironment">An instance of <see cref="IHostingEnvironment"/>.</param>
/// <param name="virtualPath">Path relative to the application root.</param>
/// <returns>Physical path corresponding to the virtual path.</returns>
public static string MapPath(
this IHostingEnvironment hostingEnvironment,
string virtualPath)
{
if (hostingEnvironment == null)
{
throw new ArgumentNullException(nameof(hostingEnvironment));
}
if (string.IsNullOrEmpty(hostingEnvironment.WebRootPath))
{
throw new InvalidOperationException("Cannot map path because webroot path is not set");
}
if (virtualPath == null)
{
return hostingEnvironment.WebRootPath;
}
// On windows replace / with \.
virtualPath = virtualPath.Replace('/', Path.DirectorySeparatorChar);
return Path.Combine(hostingEnvironment.WebRootPath, virtualPath);
}
}
}

View File

@ -1,7 +1,6 @@
// 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;
using Microsoft.Extensions.FileProviders;
namespace Microsoft.AspNetCore.Hosting
@ -17,6 +16,13 @@ namespace Microsoft.AspNetCore.Hosting
/// </summary>
// This must be settable!
string EnvironmentName { get; set; }
/// <summary>
/// Gets or sets the name of the application. This property is automatically set by the host to the assembly containing
/// the application entry point.
/// </summary>
// This must be settable!
string ApplicationName { get; set; }
/// <summary>
/// Gets or sets the absolute path to the directory that contains the web-servable application content files.
@ -31,8 +37,15 @@ namespace Microsoft.AspNetCore.Hosting
IFileProvider WebRootFileProvider { get; set; }
/// <summary>
/// Gets or sets the configuration object used by hosting environment.
/// Gets or sets the absolute path to the directory that contains the application content files.
/// </summary>
IConfiguration Configuration { get; set; }
// This must be settable!
string ContentRootPath { get; set; }
/// <summary>
/// Gets or sets an <see cref="IFileProvider"/> pointing at <see cref="ContentRootPath"/>.
/// </summary>
// This must be settable!
IFileProvider ContentRootFileProvider { get; set; }
}
}

View File

@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Hosting
public static readonly string WebRootKey = "webroot";
public static readonly string CaptureStartupErrorsKey = "captureStartupErrors";
public static readonly string ServerUrlsKey = "server.urls";
public static readonly string ApplicationBaseKey = "applicationBase";
public static readonly string ContentRootKey = "contentRoot";
public static readonly string HostingJsonFile = "hosting.json";
public static readonly string EnvironmentVariablesPrefix = "ASPNETCORE_";

View File

@ -1,19 +1,22 @@
// 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;
using Microsoft.Extensions.FileProviders;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public class HostingEnvironment : IHostingEnvironment
{
public string EnvironmentName { get; set; } = Microsoft.AspNetCore.Hosting.EnvironmentName.Production;
public string EnvironmentName { get; set; } = Hosting.EnvironmentName.Production;
public string ApplicationName { get; set; }
public string WebRootPath { get; set; }
public IFileProvider WebRootFileProvider { get; set; }
public IConfiguration Configuration { get; set; }
public string ContentRootPath { get; set; }
public IFileProvider ContentRootFileProvider { get; set; }
}
}

View File

@ -3,26 +3,40 @@
using System;
using System.IO;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.FileProviders;
namespace Microsoft.AspNetCore.Hosting.Internal
{
public static class HostingEnvironmentExtensions
{
public static void Initialize(this IHostingEnvironment hostingEnvironment, string applicationBasePath, WebHostOptions options, IConfiguration configuration)
public static void Initialize(this IHostingEnvironment hostingEnvironment, string applicationName, string contentRootPath, WebHostOptions options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
if (string.IsNullOrEmpty(applicationName))
{
throw new ArgumentException("A valid non-empty application name must be provided.", nameof(applicationName));
}
if (string.IsNullOrEmpty(contentRootPath))
{
throw new ArgumentException("A valid non-empty content root must be provided.", nameof(contentRootPath));
}
if (!Directory.Exists(contentRootPath))
{
throw new ArgumentException("The provided content root does not exist.", nameof(contentRootPath));
}
hostingEnvironment.ApplicationName = applicationName;
hostingEnvironment.ContentRootPath = contentRootPath;
hostingEnvironment.ContentRootFileProvider = new PhysicalFileProvider(hostingEnvironment.ContentRootPath);
var webRoot = options.WebRoot;
if (webRoot == null)
{
// Default to /wwwroot if it exists.
var wwwroot = Path.Combine(applicationBasePath, "wwwroot");
var wwwroot = Path.Combine(hostingEnvironment.ContentRootPath, "wwwroot");
if (Directory.Exists(wwwroot))
{
hostingEnvironment.WebRootPath = wwwroot;
@ -30,8 +44,9 @@ namespace Microsoft.AspNetCore.Hosting.Internal
}
else
{
hostingEnvironment.WebRootPath = Path.Combine(applicationBasePath, webRoot);
hostingEnvironment.WebRootPath = Path.Combine(hostingEnvironment.ContentRootPath, webRoot);
}
if (!string.IsNullOrEmpty(hostingEnvironment.WebRootPath))
{
hostingEnvironment.WebRootPath = Path.GetFullPath(hostingEnvironment.WebRootPath);
@ -45,10 +60,9 @@ namespace Microsoft.AspNetCore.Hosting.Internal
{
hostingEnvironment.WebRootFileProvider = new NullFileProvider();
}
var environmentName = options.Environment;
hostingEnvironment.EnvironmentName = environmentName ?? hostingEnvironment.EnvironmentName;
hostingEnvironment.Configuration = configuration;
}
}
}

View File

@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
Environment = configuration[WebHostDefaults.EnvironmentKey];
ServerFactoryLocation = configuration[WebHostDefaults.ServerKey];
WebRoot = configuration[WebHostDefaults.WebRootKey];
ApplicationBasePath = configuration[WebHostDefaults.ApplicationBaseKey];
ContentRootPath = configuration[WebHostDefaults.ContentRootKey];
}
public string Application { get; set; }
@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
public string WebRoot { get; set; }
public string ApplicationBasePath { get; set; }
public string ContentRootPath { get; set; }
private static bool ParseBool(IConfiguration configuration, string key)
{

View File

@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.Versioning;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting.Builder;
using Microsoft.AspNetCore.Hosting.Internal;
@ -152,14 +151,16 @@ namespace Microsoft.AspNetCore.Hosting
public IWebHost Build()
{
var hostingServices = BuildHostingServices();
var hostingContainer = hostingServices.BuildServiceProvider();
var appEnvironment = hostingContainer.GetRequiredService<IApplicationEnvironment>();
var startupLoader = hostingContainer.GetRequiredService<IStartupLoader>();
var contentRootPath = ResolveContentRootPath(_options.ContentRootPath, appEnvironment.ApplicationBasePath);
var applicationName = ResolveApplicationName() ?? appEnvironment.ApplicationName;
// Initialize the hosting environment
_hostingEnvironment.Initialize(appEnvironment.ApplicationBasePath, _options, _config);
_hostingEnvironment.Initialize(applicationName, contentRootPath, _options);
var host = new WebHost(hostingServices, startupLoader, _options, _config);
@ -201,23 +202,13 @@ namespace Microsoft.AspNetCore.Hosting
services.AddTransient<IStartupFilter, AutoRequestServicesStartupFilter>();
var defaultPlatformServices = PlatformServices.Default;
if (defaultPlatformServices != null)
if (defaultPlatformServices.Application != null)
{
if (defaultPlatformServices.Application != null)
{
var appEnv = defaultPlatformServices.Application;
var applicationBasePath = ResolveApplicationBasePath(_options.ApplicationBasePath, appEnv.ApplicationBasePath);
var startupAssemblyName = ResolveStartupAssemblyName() ?? appEnv.ApplicationName;
appEnv = new WrappedApplicationEnvironment(applicationBasePath, startupAssemblyName, defaultPlatformServices.Application);
services.TryAddSingleton(appEnv);
}
if (defaultPlatformServices.Runtime != null)
{
services.TryAddSingleton(defaultPlatformServices.Runtime);
}
services.TryAddSingleton(defaultPlatformServices.Application);
}
if (defaultPlatformServices.Runtime != null)
{
services.TryAddSingleton(defaultPlatformServices.Runtime);
}
foreach (var configureServices in _configureServicesDelegates)
@ -228,20 +219,20 @@ namespace Microsoft.AspNetCore.Hosting
return services;
}
private string ResolveApplicationBasePath(string applicationBasePath, string basePath)
private string ResolveContentRootPath(string contentRootPath, string basePath)
{
if (string.IsNullOrEmpty(applicationBasePath))
if (string.IsNullOrEmpty(contentRootPath))
{
return basePath;
}
if (Path.IsPathRooted(applicationBasePath))
if (Path.IsPathRooted(contentRootPath))
{
return applicationBasePath;
return contentRootPath;
}
return Path.Combine(Path.GetFullPath(basePath), applicationBasePath);
return Path.Combine(Path.GetFullPath(basePath), contentRootPath);
}
private string ResolveStartupAssemblyName()
private string ResolveApplicationName()
{
if (_startup != null)
{
@ -257,24 +248,5 @@ namespace Microsoft.AspNetCore.Hosting
}
return null;
}
private class WrappedApplicationEnvironment : IApplicationEnvironment
{
public WrappedApplicationEnvironment(string applicationBasePath, string applicationName, IApplicationEnvironment env)
{
ApplicationBasePath = applicationBasePath;
ApplicationName = applicationName;
ApplicationVersion = env.ApplicationVersion;
RuntimeFramework = env.RuntimeFramework;
}
public string ApplicationBasePath { get; }
public string ApplicationName { get; }
public string ApplicationVersion { get; }
public FrameworkName RuntimeFramework { get; }
}
}
}

View File

@ -62,14 +62,14 @@ namespace Microsoft.AspNetCore.Hosting
return hostBuilder.UseServer(new ServerFactory(server));
}
public static IWebHostBuilder UseApplicationBasePath(this IWebHostBuilder hostBuilder, string applicationBasePath)
public static IWebHostBuilder UseContentRoot(this IWebHostBuilder hostBuilder, string contentRootPath)
{
if (applicationBasePath == null)
if (contentRootPath == null)
{
throw new ArgumentNullException(nameof(applicationBasePath));
throw new ArgumentNullException(nameof(contentRootPath));
}
return hostBuilder.UseSetting(WebHostDefaults.ApplicationBaseKey, applicationBasePath);
return hostBuilder.UseSetting(WebHostDefaults.ContentRootKey, contentRootPath);
}
public static IWebHostBuilder UseEnvironment(this IWebHostBuilder hostBuilder, string environment)

View File

@ -5,7 +5,6 @@ using System;
using System.Threading;
using Microsoft.AspNetCore.Server.Features;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.AspNetCore.Hosting
{
@ -49,10 +48,9 @@ namespace Microsoft.AspNetCore.Hosting
var hostingEnvironment = host.Services.GetService<IHostingEnvironment>();
var applicationLifetime = host.Services.GetService<IApplicationLifetime>();
var applicationEnvironment = host.Services.GetService<IApplicationEnvironment>();
Console.WriteLine($"Hosting environment: {hostingEnvironment.EnvironmentName}");
Console.WriteLine($"Application base path: {applicationEnvironment.ApplicationBasePath}");
Console.WriteLine($"Content root path: {hostingEnvironment.ContentRootPath}");
var serverAddresses = host.ServerFeatures.Get<IServerAddressesFeature>()?.Addresses;
if (serverAddresses != null)

View File

@ -1,10 +1,8 @@
// 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.IO;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.FileProviders;
using Xunit;
@ -17,9 +15,11 @@ namespace Microsoft.AspNetCore.Hosting.Tests
{
var env = new HostingEnvironment();
env.Initialize(".", new WebHostOptions() {WebRoot = "testroot"}, null);
env.Initialize("DummyApplication", Path.GetFullPath("."), new WebHostOptions(){ WebRoot = "testroot" });
Assert.Equal(Path.GetFullPath("."), env.ContentRootPath);
Assert.Equal(Path.GetFullPath("testroot"), env.WebRootPath);
Assert.IsAssignableFrom<PhysicalFileProvider>(env.ContentRootFileProvider);
Assert.IsAssignableFrom<PhysicalFileProvider>(env.WebRootFileProvider);
}
@ -28,9 +28,11 @@ namespace Microsoft.AspNetCore.Hosting.Tests
{
var env = new HostingEnvironment();
env.Initialize("testroot", new WebHostOptions(), null);
env.Initialize("DummyApplication", Path.GetFullPath("testroot"), new WebHostOptions());
Assert.Equal(Path.GetFullPath(Path.Combine("testroot","wwwroot")), env.WebRootPath);
Assert.Equal(Path.GetFullPath("testroot"), env.ContentRootPath);
Assert.Equal(Path.GetFullPath(Path.Combine("testroot", "wwwroot")), env.WebRootPath);
Assert.IsAssignableFrom<PhysicalFileProvider>(env.ContentRootFileProvider);
Assert.IsAssignableFrom<PhysicalFileProvider>(env.WebRootFileProvider);
}
@ -39,43 +41,23 @@ namespace Microsoft.AspNetCore.Hosting.Tests
{
var env = new HostingEnvironment();
env.Initialize(Path.Combine("testroot", "wwwroot"), new WebHostOptions(), null);
env.Initialize("DummyApplication", Path.GetFullPath(Path.Combine("testroot", "wwwroot")), new WebHostOptions());
Assert.Equal(Path.GetFullPath(Path.Combine("testroot", "wwwroot")), env.ContentRootPath);
Assert.Null(env.WebRootPath);
Assert.IsAssignableFrom<PhysicalFileProvider>(env.ContentRootFileProvider);
Assert.IsAssignableFrom<NullFileProvider>(env.WebRootFileProvider);
}
[Fact]
public void SetsConfiguration()
{
var config = new ConfigurationBuilder().Build();
var env = new HostingEnvironment();
env.Initialize(".", new WebHostOptions(), config);
Assert.Same(config, env.Configuration);
}
[Fact]
public void OverridesEnvironmentFromConfig()
{
var env = new HostingEnvironment();
env.EnvironmentName = "SomeName";
env.Initialize(".", new WebHostOptions() { Environment = "NewName" }, null);
env.Initialize("DummyApplication", Path.GetFullPath("."), new WebHostOptions(){ Environment = "NewName" });
Assert.Equal("NewName", env.EnvironmentName);
}
[Fact]
public void MapPathThrowsWithNoWwwroot()
{
var env = new HostingEnvironment();
env.Initialize(".", new WebHostOptions(), null);
Assert.Throws<InvalidOperationException>(() => env.MapPath("file.txt"));
}
}
}

View File

@ -322,27 +322,38 @@ namespace Microsoft.AspNetCore.Hosting
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseApplicationBasePath("/foo/bar")
.UseContentRoot("/")
.UseServer(new TestServer())
.UseStartup("Microsoft.AspNetCore.Hosting.Tests")
.Build();
Assert.Equal("/foo/bar", host.Services.GetService<IApplicationEnvironment>().ApplicationBasePath);
Assert.Equal("/", host.Services.GetService<IHostingEnvironment>().ContentRootPath);
}
[Fact]
public void RelativeApplicationBaseAreResolved()
public void RelativeContentRootIsResolved()
{
var builder = new ConfigurationBuilder();
var host = new WebHostBuilder()
.UseApplicationBasePath("bar")
.UseContentRoot("testroot")
.UseServer(new TestServer())
.UseStartup("Microsoft.AspNetCore.Hosting.Tests")
.Build();
var basePath = host.Services.GetRequiredService<IApplicationEnvironment>().ApplicationBasePath;
var basePath = host.Services.GetRequiredService<IHostingEnvironment>().ContentRootPath;
Assert.True(Path.IsPathRooted(basePath));
Assert.EndsWith(Path.DirectorySeparatorChar + "bar", basePath);
Assert.EndsWith(Path.DirectorySeparatorChar + "testroot", basePath);
}
[Fact]
public void DefaultContentRootIsApplicationBasePath()
{
var host = new WebHostBuilder()
.UseServer(new TestServer())
.UseStartup("Microsoft.AspNetCore.Hosting.Tests")
.Build();
var appBase = PlatformServices.Default.Application.ApplicationBasePath;
Assert.Equal(appBase, host.Services.GetService<IHostingEnvironment>().ContentRootPath);
}
[Fact]
@ -354,8 +365,11 @@ namespace Microsoft.AspNetCore.Hosting
.UseStartup("Microsoft.AspNetCore.Hosting.Tests")
.Build();
var hostingEnv = host.Services.GetService<IHostingEnvironment>();
Assert.Equal("Microsoft.AspNetCore.Hosting.Tests", hostingEnv.ApplicationName);
var appEnv = host.Services.GetService<IApplicationEnvironment>();
Assert.Equal("Microsoft.AspNetCore.Hosting.Tests", appEnv.ApplicationName);
Assert.Equal(PlatformServices.Default.Application.ApplicationName, appEnv.ApplicationName);
Assert.Equal(PlatformServices.Default.Application.ApplicationBasePath, appEnv.ApplicationBasePath);
}
[Fact]
@ -368,8 +382,11 @@ namespace Microsoft.AspNetCore.Hosting
.UseStartup("Microsoft.AspNetCore.Hosting.Tests.NonExistent")
.Build();
var hostingEnv = host.Services.GetService<IHostingEnvironment>();
Assert.Equal("Microsoft.AspNetCore.Hosting.Tests", hostingEnv.ApplicationName);
var appEnv = host.Services.GetService<IApplicationEnvironment>();
Assert.Equal("Microsoft.AspNetCore.Hosting.Tests", appEnv.ApplicationName);
Assert.Equal(PlatformServices.Default.Application.ApplicationName, appEnv.ApplicationName);
Assert.Equal(PlatformServices.Default.Application.ApplicationBasePath, appEnv.ApplicationBasePath);
}
[Fact]
@ -382,8 +399,11 @@ namespace Microsoft.AspNetCore.Hosting
.UseStartup("Microsoft.AspNetCore.Hosting.Tests.NonExistent")
.Build();
var hostingEnv = host.Services.GetService<IHostingEnvironment>();
Assert.Equal("Microsoft.AspNetCore.Hosting.Tests", hostingEnv.ApplicationName);
var appEnv = host.Services.GetService<IApplicationEnvironment>();
Assert.Equal("Microsoft.AspNetCore.Hosting.Tests", appEnv.ApplicationName);
Assert.Equal(PlatformServices.Default.Application.ApplicationName, appEnv.ApplicationName);
Assert.Equal(PlatformServices.Default.Application.ApplicationBasePath, appEnv.ApplicationBasePath);
}
private IWebHostBuilder CreateWebHostBuilder()

View File

@ -15,7 +15,6 @@ using Microsoft.AspNetCore.Hosting.Startup;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Features;
using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@ -125,24 +124,6 @@ namespace Microsoft.AspNetCore.Hosting
Assert.Equal("http://localhost:5000", host.ServerFeatures.Get<IServerAddressesFeature>().Addresses.First());
}
[Fact]
public void FlowsConfig()
{
var vals = new Dictionary<string, string>
{
{ "Server", "Microsoft.AspNetCore.Hosting.Tests" }
};
var builder = new ConfigurationBuilder()
.AddInMemoryCollection(vals);
var config = builder.Build();
var host = CreateBuilder(config).Build();
host.Start();
var hostingEnvironment = host.Services.GetService<IHostingEnvironment>();
Assert.NotNull(hostingEnvironment.Configuration);
Assert.Equal("Microsoft.AspNetCore.Hosting.Tests", hostingEnvironment.Configuration["Server"]);
}
[Fact]
public void WebHostCanBeStarted()
{
@ -277,23 +258,6 @@ namespace Microsoft.AspNetCore.Hosting
Assert.Equal(EnvironmentName.Production, env.EnvironmentName);
}
[Fact]
public void EnvDefaultsToConfigValueIfSpecifiedWithOldKey()
{
var vals = new Dictionary<string, string>
{
{ "environment", "Staging" }
};
var builder = new ConfigurationBuilder()
.AddInMemoryCollection(vals);
var config = builder.Build();
var host = CreateBuilder(config).UseServer((IServerFactory)this).Build();
var env = host.Services.GetService<IHostingEnvironment>();
Assert.Equal("Staging", env.EnvironmentName);
}
[Fact]
public void EnvDefaultsToConfigValueIfSpecified()
{
@ -342,27 +306,6 @@ namespace Microsoft.AspNetCore.Hosting
}
}
[Theory]
[InlineData(null, "")]
[InlineData("", "")]
[InlineData("/", "/")]
[InlineData(@"\", @"\")]
[InlineData("sub", "sub")]
[InlineData("sub/sub2/sub3", @"sub/sub2/sub3")]
public void MapPath_Facts(string virtualPath, string expectedSuffix)
{
RunMapPath(virtualPath, expectedSuffix);
}
[ConditionalTheory]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(@"sub/sub2\sub3\", @"sub/sub2/sub3/")]
public void MapPath_Windows_Facts(string virtualPath, string expectedSuffix)
{
RunMapPath(virtualPath, expectedSuffix);
}
[Fact]
public void WebHost_CreatesDefaultRequestIdentifierFeature_IfNotPresent()
{
@ -470,23 +413,6 @@ namespace Microsoft.AspNetCore.Hosting
return builder.Build();
}
private void RunMapPath(string virtualPath, string expectedSuffix)
{
var host = CreateBuilder().UseServer((IServerFactory)this).Build();
using (host)
{
host.Start();
var env = host.Services.GetRequiredService<IHostingEnvironment>();
// MapPath requires webroot to be set, we don't care
// about file provider so just set it here
env.WebRootPath = ".";
var mappedPath = env.MapPath(virtualPath);
expectedSuffix = expectedSuffix.Replace('/', Path.DirectorySeparatorChar);
Assert.Equal(Path.Combine(env.WebRootPath, expectedSuffix), mappedPath);
}
}
private IWebHostBuilder CreateBuilder(IConfiguration config = null)
{
return new WebHostBuilder().UseConfiguration(config ?? new ConfigurationBuilder().Build()).UseStartup("Microsoft.AspNetCore.Hosting.Tests");