/// <summary> /// Runs 'dotnet run' on the specified project while only exposing a HTTP endpoint. /// </summary> /// <param name="project">The project.</param> /// <param name="projectRelativeDirectoryPath">The project relative directory path.</param> /// <param name="action">The action to perform while the project is running.</param> /// <param name="noRestore">Whether to restore the project.</param> /// <param name="validateCertificate">Validate the project certificate.</param> /// <param name="timeout">The timeout.</param> /// <returns>A task representing the operation.</returns> public static async Task DotnetRun( this Project project, string projectRelativeDirectoryPath, Func <HttpClient, Task> action, bool?noRestore = true, Func <HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool> validateCertificate = null, TimeSpan?timeout = null) { var httpPort = PortHelper.GetFreeTcpPort(); var httpUrl = $"http://localhost:{httpPort}"; var projectFilePath = Path.Combine(project.DirectoryPath, projectRelativeDirectoryPath); var dotnetRun = await DotnetRunInternal(projectFilePath, noRestore, timeout, httpUrl); var httpClientHandler = new HttpClientHandler() { AllowAutoRedirect = false, ServerCertificateCustomValidationCallback = validateCertificate ?? DefaultValidateCertificate, }; var httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(httpUrl) }; try { await action(httpClient); } finally { httpClient.Dispose(); httpClientHandler.Dispose(); dotnetRun.Dispose(); } }
/// <summary> /// Runs 'dotnet run' on the specified project while only exposing a HTTP and HTTPS endpoint. /// </summary> /// <param name="project">The project.</param> /// <param name="projectRelativeDirectoryPath">The project relative directory path.</param> /// <param name="readinessCheck">The readiness check to perform to check that the app has started.</param> /// <param name="action">The action to perform while the project is running.</param> /// <param name="noRestore">Whether to restore the project.</param> /// <param name="validateCertificate">Validate the project certificate.</param> /// <param name="timeout">The timeout.</param> /// <param name="showShellWindow">if set to <c>true</c> show the shell window instead of logging to output.</param> /// <returns>A task representing the operation.</returns> public static async Task DotnetRunAsync( this Project project, string projectRelativeDirectoryPath, Func <HttpClient, HttpClient, Task <bool> > readinessCheck, Func <HttpClient, HttpClient, Task> action, bool?noRestore = true, Func <HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool> validateCertificate = null, TimeSpan?timeout = null, bool showShellWindow = false) { if (project is null) { throw new ArgumentNullException(nameof(project)); } if (projectRelativeDirectoryPath is null) { throw new ArgumentNullException(nameof(projectRelativeDirectoryPath)); } if (action is null) { throw new ArgumentNullException(nameof(action)); } var httpPort = PortHelper.GetFreeTcpPort(); var httpsPort = PortHelper.GetFreeTcpPort(); var httpUrl = new Uri($"http://localhost:{httpPort}"); var httpsUrl = new Uri($"https://localhost:{httpsPort}"); var httpClientHandler = new HttpClientHandler() { AllowAutoRedirect = false, ServerCertificateCustomValidationCallback = validateCertificate ?? DefaultValidateCertificate, }; var httpClient = new HttpClient(httpClientHandler) { BaseAddress = httpUrl }; var httpsClient = new HttpClient(httpClientHandler) { BaseAddress = httpsUrl }; var projectFilePath = Path.Combine(project.DirectoryPath, projectRelativeDirectoryPath); var dotnetRun = await DotnetRunInternalAsync( readinessCheck, httpClient, httpsClient, projectFilePath, noRestore, timeout, showShellWindow, httpUrl, httpsUrl) .ConfigureAwait(false); try { await action(httpClient, httpsClient).ConfigureAwait(false); } finally { httpClient.Dispose(); httpsClient.Dispose(); httpClientHandler.Dispose(); await dotnetRun.DisposeAsync().ConfigureAwait(false); } }