diff --git a/src/Hosting/TestHost/src/WebHostBuilderExtensions.cs b/src/Hosting/TestHost/src/WebHostBuilderExtensions.cs index cbdb7e06e989..7f0af264c182 100644 --- a/src/Hosting/TestHost/src/WebHostBuilderExtensions.cs +++ b/src/Hosting/TestHost/src/WebHostBuilderExtensions.cs @@ -163,6 +163,23 @@ public static IWebHostBuilder UseSolutionRelativeContentRoot( } while (directoryInfo is not null); + if (string.Equals(solutionName, "*.sln", StringComparison.OrdinalIgnoreCase)) + { + directoryInfo = new DirectoryInfo(applicationBasePath); + do + { + var solutionPath = Directory.EnumerateFiles(directoryInfo.FullName, "*.slnx").FirstOrDefault(); + if (solutionPath != null) + { + builder.UseContentRoot(Path.GetFullPath(Path.Combine(directoryInfo.FullName, solutionRelativePath))); + return builder; + } + + directoryInfo = directoryInfo.Parent; + } + while (directoryInfo is not null); + } + throw new InvalidOperationException($"Solution root could not be located using application root {applicationBasePath}."); } diff --git a/src/Hosting/TestHost/test/WebHostBuilderExtensionsTests.cs b/src/Hosting/TestHost/test/WebHostBuilderExtensionsTests.cs new file mode 100644 index 000000000000..664b362b9b35 --- /dev/null +++ b/src/Hosting/TestHost/test/WebHostBuilderExtensionsTests.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using Microsoft.AspNetCore.Hosting; +using Xunit; + +namespace Microsoft.AspNetCore.TestHost; + +public class WebHostBuilderExtensionsTests +{ + [Fact] + public void UseSolutionRelativeContentRoot_FallsBackToSlnx() + { + var rootPath = Path.Combine(Path.GetTempPath(), "slnx-" + Guid.NewGuid().ToString("n")); + var applicationBasePath = Path.Combine(rootPath, "src", "MyApp", "bin"); + + try + { + Directory.CreateDirectory(applicationBasePath); + File.WriteAllText(Path.Combine(rootPath, "Test.slnx"), string.Empty); + Directory.CreateDirectory(Path.Combine(rootPath, "src", "MyApp")); + + var builder = new WebHostBuilder(); + + builder.UseSolutionRelativeContentRoot("src/MyApp", applicationBasePath, "*.sln"); + + Assert.Equal(Path.GetFullPath(Path.Combine(rootPath, "src", "MyApp")), builder.GetSetting(WebHostDefaults.ContentRootKey)); + } + finally + { + if (Directory.Exists(rootPath)) + { + Directory.Delete(rootPath, recursive: true); + } + } + } + + [Fact] + public void UseSolutionRelativeContentRoot_PrefersSlnOverSlnx() + { + var rootPath = Path.Combine(Path.GetTempPath(), "sln-" + Guid.NewGuid().ToString("n")); + var applicationBasePath = Path.Combine(rootPath, "child", "content", "bin"); + + try + { + Directory.CreateDirectory(applicationBasePath); + File.WriteAllText(Path.Combine(rootPath, "Parent.sln"), string.Empty); + File.WriteAllText(Path.Combine(rootPath, "child", "Child.slnx"), string.Empty); + Directory.CreateDirectory(Path.Combine(rootPath, "parentContent")); + + var builder = new WebHostBuilder(); + + builder.UseSolutionRelativeContentRoot("parentContent", applicationBasePath, "*.sln"); + + Assert.Equal(Path.GetFullPath(Path.Combine(rootPath, "parentContent")), builder.GetSetting(WebHostDefaults.ContentRootKey)); + } + finally + { + if (Directory.Exists(rootPath)) + { + Directory.Delete(rootPath, recursive: true); + } + } + } +}