运行测试时,自动启动WebApi项目。

main
wanggaofeng 1 year ago
parent d2a3c189de
commit a1c233a80b

@ -1,5 +1,6 @@
{ {
"WebApi": { "WebApi": {
"BaseUrl": "http://localhost:5189" "BaseUrl": "http://localhost:5189",
"WebAppMutexName": "HttpClientStudy.WebApp"
} }
} }

@ -2,6 +2,8 @@
{ {
public class WebApiConfig public class WebApiConfig
{ {
public string BaseUrl { get; set; } public string BaseUrl { get; set; } = "http://localhost:5189";
public string WebAppMutexName { get; set; } = "HttpClientStudy.WebApp";
} }
} }

@ -27,7 +27,7 @@ namespace HttpClientStudy.Config
/// <summary> /// <summary>
/// 添加WebApi配置文件 /// 添加WebApi配置文件
/// </summary> /// </summary>
public static IConfigurationBuilder AddWebApiConfigration(this IConfigurationBuilder configuration) public static IConfigurationBuilder AddWebApiConfiguration(this IConfigurationBuilder configuration)
{ {
configuration.AddJsonFile($"ConfigFiles/Config.json", optional: false, reloadOnChange: true); configuration.AddJsonFile($"ConfigFiles/Config.json", optional: false, reloadOnChange: true);
configuration.AddJsonFile($"ConfigFiles/Config.{System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true, reloadOnChange: true); configuration.AddJsonFile($"ConfigFiles/Config.{System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true, reloadOnChange: true);
@ -45,6 +45,11 @@ namespace HttpClientStudy.Config
services.AddOptions(); services.AddOptions();
var configuration = services.BuildServiceProvider().GetService<IConfiguration>(); var configuration = services.BuildServiceProvider().GetService<IConfiguration>();
if (configuration == null)
{
throw new InvalidOperationException("Configuration is not configured.");
}
services.Configure<WebApiConfig>(configuration.GetSection("WebApi")); services.Configure<WebApiConfig>(configuration.GetSection("WebApi"));
return services; return services;

@ -21,7 +21,7 @@ namespace HttpClientStudy.Config
public static IOptionsMonitor<WebApiConfig> GetWebApiConfigOption() public static IOptionsMonitor<WebApiConfig> GetWebApiConfigOption()
{ {
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddWebApiConfigration(); configurationBuilder.AddWebApiConfiguration();
ServiceCollection services = new ServiceCollection(); ServiceCollection services = new ServiceCollection();
services.AddSingleton<IConfiguration>(configurationBuilder.Build()); services.AddSingleton<IConfiguration>(configurationBuilder.Build());

@ -1,6 +1,7 @@
global using System; global using System;
global using System.Linq; global using System.Linq;
global using System.Text; global using System.Text;
global using System.Threading;
global using System.Threading.Tasks; global using System.Threading.Tasks;
global using System.Collections.Generic; global using System.Collections.Generic;

@ -19,21 +19,23 @@ namespace HttpClientStudy.UnitTest.ConfigTest
public void WebApiOption_Test() public void WebApiOption_Test()
{ {
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddWebApiConfigration(); configurationBuilder.AddWebApiConfiguration();
IConfiguration configuration = configurationBuilder.Build(); IConfiguration configuration = configurationBuilder.Build();
var services = new ServiceCollection(); var services = new ServiceCollection();
services.AddSingleton<IConfiguration>(configuration); services.AddSingleton(configuration);
services.AddWebApiOptions(); services.AddWebApiOptions();
var provider = services.BuildServiceProvider(); var provider = services.BuildServiceProvider();
IOptions<Config.WebApiConfig> webApiOptions = provider.GetService<IOptions<Config.WebApiConfig>>(); IOptions<WebApiConfig>? webApiOptions = provider.GetService<IOptions<WebApiConfig>>();
var webApiConfig = webApiOptions.Value; var webApiConfig = webApiOptions?.Value;
Assert.NotNull(webApiOptions); Assert.NotNull(webApiOptions);
Assert.NotNull(webApiConfig);
Assert.NotEmpty(webApiConfig.BaseUrl); Assert.NotEmpty(webApiConfig.BaseUrl);
Assert.NotEmpty(webApiConfig.WebAppMutexName);
} }
[Fact] [Fact]
@ -46,6 +48,7 @@ namespace HttpClientStudy.UnitTest.ConfigTest
var webApiConfig = webApiMonitor.CurrentValue; var webApiConfig = webApiMonitor.CurrentValue;
Assert.NotNull(webApiConfig); Assert.NotNull(webApiConfig);
Assert.NotEmpty(webApiConfig.WebAppMutexName);
} }
} }
} }

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace HttpClientStudy.UnitTest
{
public class StartupTest
{
[Fact]
public void StartWebApiProject()
{
var startup = new Startup();
startup.StartWebApiProject();
}
}
}

@ -25,7 +25,7 @@ namespace HttpClientStudy.UnitTest
/// <returns></returns> /// <returns></returns>
public IHostBuilder CreateHostBuilder() public IHostBuilder CreateHostBuilder()
{ {
return Host.CreateDefaultBuilder() ; return Host.CreateDefaultBuilder();
} }
/// <summary> /// <summary>
@ -34,6 +34,9 @@ namespace HttpClientStudy.UnitTest
/// <param name="hostBuilder"></param> /// <param name="hostBuilder"></param>
public void ConfigureHost(IHostBuilder hostBuilder) public void ConfigureHost(IHostBuilder hostBuilder)
{ {
//确保启动webapi项目
StartWebApiProject();
hostBuilder hostBuilder
//主机配置 //主机配置
.ConfigureHostConfiguration(builder => .ConfigureHostConfiguration(builder =>
@ -71,9 +74,9 @@ namespace HttpClientStudy.UnitTest
/// 注册服务:必须 /// 注册服务:必须
/// </summary> /// </summary>
/// <param name="services"></param> /// <param name="services"></param>
public void ConfigureServices(IServiceCollection services,HostBuilderContext context) public void ConfigureServices(IServiceCollection services, HostBuilderContext context)
{ {
Debugger.Log(1,"DI","ConfigureServices"); Debugger.Log(1, "DI", "ConfigureServices");
} }
private class WebApiStartup private class WebApiStartup
@ -85,5 +88,52 @@ namespace HttpClientStudy.UnitTest
app.Run(static context => context.Response.WriteAsync("xxxxxx")); app.Run(static context => context.Response.WriteAsync("xxxxxx"));
} }
} }
/// <summary>
/// 启动webapi项目
/// (出现webapi项目启动命令行窗口)
/// </summary>
public void StartWebApiProject()
{
string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName;
//webapi项目不在运行状态则启动webapi项目
if (webAppIsRunningByMutex() == false)
{
//VS项目根目录
string vsProjectPath = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory)!.Parent!.Parent!.Parent!.Parent!.FullName;
//webapi项目根项目
string webApiProjectPath = Path.Combine(vsProjectPath, projectAndMutexName);
//启动命令信息
var prossInfo = new ProcessStartInfo("dotnet", $"run --project {webApiProjectPath}")
{
UseShellExecute = true,
CreateNoWindow = false,
RedirectStandardOutput = false
};
//启动
Process.Start(prossInfo);
}
//由进程名判断
//bool webAppIsRunningByProcessName()
//{
// return Process.GetProcessesByName(projectAndMutexName).ToList().Count == 0;
//}
//由互斥锁判断
bool webAppIsRunningByMutex()
{
//创建互斥锁
_ = new Mutex(true, projectAndMutexName, out bool createdResult);
//互斥锁是否创建成功
return !createdResult;
}
}
} }
} }

@ -35,9 +35,6 @@ namespace HttpClientStudy.WebApp.Controllers
public IActionResult Error500() public IActionResult Error500()
{ {
throw new System.Exception("服务器异常"); throw new System.Exception("服务器异常");
var result = BaseResultUtil.Success("服务器异常");
return new JsonResult(result);
} }
} }
} }

@ -1,8 +1,8 @@
using System.Text; using System.Text;
using System.Diagnostics;
using HttpClientStudy.Model; using System.Threading ;
using HttpClientStudy.Service; using System.Collections.Generic;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
@ -10,6 +10,10 @@ using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using HttpClientStudy.Model;
using HttpClientStudy.Service;
using HttpClientStudy.Config;
namespace HttpClientStudy.WebApp namespace HttpClientStudy.WebApp
{ {
/// <summary> /// <summary>
@ -41,7 +45,7 @@ namespace HttpClientStudy.WebApp
}); });
//配置Kestrel服务器选项 //配置Kestrel服务器选项
builder.Services.Configure<KestrelServerOptions>( option => builder.Services.Configure<KestrelServerOptions>(option =>
{ {
//ASP.NET Core 3.0 之前的版本AllowSynchronousIO 默认是开启的 //ASP.NET Core 3.0 之前的版本AllowSynchronousIO 默认是开启的
//设置 true :允许同步 IO 操作,这样允许接收Get请求中的请求体数据.但只能直接从流中读取,不能自动模型绑定。 //设置 true :允许同步 IO 操作,这样允许接收Get请求中的请求体数据.但只能直接从流中读取,不能自动模型绑定。

Loading…
Cancel
Save