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

main
wanggaofeng 11 months 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,16 +34,19 @@ 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 =>
{ {
}) })
//应用配置 //应用配置
.ConfigureAppConfiguration((context, builder) => .ConfigureAppConfiguration((context, builder) =>
{ {
}); });
hostBuilder.ConfigureWebHost(webHostBuilder => hostBuilder.ConfigureWebHost(webHostBuilder =>
@ -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
@ -81,9 +84,56 @@ namespace HttpClientStudy.UnitTest
public void ConfigureServices(IServiceCollection services) => services.AddLogging(lb => lb.AddXunitOutput()); public void ConfigureServices(IServiceCollection services) => services.AddLogging(lb => lb.AddXunitOutput());
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)
{ {
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>
@ -33,7 +37,7 @@ namespace HttpClientStudy.WebApp
builder.Services.AddDistributedMemoryCache(); builder.Services.AddDistributedMemoryCache();
//配置Session //配置Session
builder.Services.AddSession(option => builder.Services.AddSession(option =>
{ {
option.Cookie.Name = "HttpClientStudy"; option.Cookie.Name = "HttpClientStudy";
option.IOTimeout = TimeSpan.FromHours(1); option.IOTimeout = TimeSpan.FromHours(1);
@ -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请求中的请求体数据.但只能直接从流中读取,不能自动模型绑定。
@ -49,7 +53,7 @@ namespace HttpClientStudy.WebApp
}); });
//配置Form表单提交选项 //配置Form表单提交选项
builder.Services.Configure<FormOptions>(options => builder.Services.Configure<FormOptions>(options =>
{ {
//options.BufferBody = true; //options.BufferBody = true;
options.MultipartBodyLengthLimit = long.MaxValue; options.MultipartBodyLengthLimit = long.MaxValue;
@ -116,11 +120,11 @@ namespace HttpClientStudy.WebApp
}); });
//配置CORS跨域 //配置CORS跨域
builder.Services.AddCors(option => builder.Services.AddCors(option =>
{ {
option.AddPolicy("AllowAll", builder => option.AddPolicy("AllowAll", builder =>
{ {
builder.SetIsOriginAllowed(_ => true).AllowAnyMethod().AllowAnyHeader().AllowCredentials(); builder.SetIsOriginAllowed(_ => true).AllowAnyMethod().AllowAnyHeader().AllowCredentials();
}); });
}); });
@ -174,7 +178,7 @@ namespace HttpClientStudy.WebApp
#endregion #endregion
var app = builder.Build(); var app = builder.Build();
#region 配置Http管道 #region 配置Http管道
//耗时统计中间件 //耗时统计中间件

Loading…
Cancel
Save