From a1c233a80bef1c736439c954def093fcc2205887 Mon Sep 17 00:00:00 2001 From: wanggaofeng <15601716045@163.com> Date: Tue, 12 Mar 2024 15:21:40 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=B5=8B=E8=AF=95=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E8=87=AA=E5=8A=A8=E5=90=AF=E5=8A=A8WebApi=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ConfigFiles/Config.json | 3 +- HttpClientStudy.Config/WebApiConfig.cs | 4 +- .../WebApiConfigExtensions.cs | 7 +- HttpClientStudy.Config/WebApiConfigManager.cs | 2 +- HttpClientStudy.Core/GlobalUsings.cs | 1 + .../ConfigTest/WebApiConfigTest.cs | 11 +-- HttpClientStudy.UnitTest/StartupTest.cs | 20 ++++++ HttpClientStudy.UnitTest/startup.cs | 68 ++++++++++++++++--- .../Controllers/ErrorDemoController.cs | 3 - HttpClientStudy.WebApp/Program.cs | 24 ++++--- 10 files changed, 113 insertions(+), 30 deletions(-) create mode 100644 HttpClientStudy.UnitTest/StartupTest.cs diff --git a/HttpClientStudy.Config/ConfigFiles/Config.json b/HttpClientStudy.Config/ConfigFiles/Config.json index 5744e5b..007c557 100644 --- a/HttpClientStudy.Config/ConfigFiles/Config.json +++ b/HttpClientStudy.Config/ConfigFiles/Config.json @@ -1,5 +1,6 @@ { "WebApi": { - "BaseUrl": "http://localhost:5189" + "BaseUrl": "http://localhost:5189", + "WebAppMutexName": "HttpClientStudy.WebApp" } } \ No newline at end of file diff --git a/HttpClientStudy.Config/WebApiConfig.cs b/HttpClientStudy.Config/WebApiConfig.cs index 9f2aca1..6758831 100644 --- a/HttpClientStudy.Config/WebApiConfig.cs +++ b/HttpClientStudy.Config/WebApiConfig.cs @@ -2,6 +2,8 @@ { public class WebApiConfig { - public string BaseUrl { get; set; } + public string BaseUrl { get; set; } = "http://localhost:5189"; + + public string WebAppMutexName { get; set; } = "HttpClientStudy.WebApp"; } } diff --git a/HttpClientStudy.Config/WebApiConfigExtensions.cs b/HttpClientStudy.Config/WebApiConfigExtensions.cs index 1cca332..40ed7d4 100644 --- a/HttpClientStudy.Config/WebApiConfigExtensions.cs +++ b/HttpClientStudy.Config/WebApiConfigExtensions.cs @@ -27,7 +27,7 @@ namespace HttpClientStudy.Config /// /// 添加WebApi配置文件 /// - 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.{System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true, reloadOnChange: true); @@ -45,6 +45,11 @@ namespace HttpClientStudy.Config services.AddOptions(); var configuration = services.BuildServiceProvider().GetService(); + if (configuration == null) + { + throw new InvalidOperationException("Configuration is not configured."); + } + services.Configure(configuration.GetSection("WebApi")); return services; diff --git a/HttpClientStudy.Config/WebApiConfigManager.cs b/HttpClientStudy.Config/WebApiConfigManager.cs index a7d1db9..4547040 100644 --- a/HttpClientStudy.Config/WebApiConfigManager.cs +++ b/HttpClientStudy.Config/WebApiConfigManager.cs @@ -21,7 +21,7 @@ namespace HttpClientStudy.Config public static IOptionsMonitor GetWebApiConfigOption() { ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); - configurationBuilder.AddWebApiConfigration(); + configurationBuilder.AddWebApiConfiguration(); ServiceCollection services = new ServiceCollection(); services.AddSingleton(configurationBuilder.Build()); diff --git a/HttpClientStudy.Core/GlobalUsings.cs b/HttpClientStudy.Core/GlobalUsings.cs index 6a3bf72..803bacb 100644 --- a/HttpClientStudy.Core/GlobalUsings.cs +++ b/HttpClientStudy.Core/GlobalUsings.cs @@ -1,6 +1,7 @@ global using System; global using System.Linq; global using System.Text; +global using System.Threading; global using System.Threading.Tasks; global using System.Collections.Generic; diff --git a/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs b/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs index c3ae6b9..ed933fb 100644 --- a/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs +++ b/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs @@ -19,21 +19,23 @@ namespace HttpClientStudy.UnitTest.ConfigTest public void WebApiOption_Test() { ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); - configurationBuilder.AddWebApiConfigration(); + configurationBuilder.AddWebApiConfiguration(); IConfiguration configuration = configurationBuilder.Build(); var services = new ServiceCollection(); - services.AddSingleton(configuration); + services.AddSingleton(configuration); services.AddWebApiOptions(); var provider = services.BuildServiceProvider(); - IOptions webApiOptions = provider.GetService>(); + IOptions? webApiOptions = provider.GetService>(); - var webApiConfig = webApiOptions.Value; + var webApiConfig = webApiOptions?.Value; Assert.NotNull(webApiOptions); + Assert.NotNull(webApiConfig); Assert.NotEmpty(webApiConfig.BaseUrl); + Assert.NotEmpty(webApiConfig.WebAppMutexName); } [Fact] @@ -46,6 +48,7 @@ namespace HttpClientStudy.UnitTest.ConfigTest var webApiConfig = webApiMonitor.CurrentValue; Assert.NotNull(webApiConfig); + Assert.NotEmpty(webApiConfig.WebAppMutexName); } } } diff --git a/HttpClientStudy.UnitTest/StartupTest.cs b/HttpClientStudy.UnitTest/StartupTest.cs new file mode 100644 index 0000000..cec67ca --- /dev/null +++ b/HttpClientStudy.UnitTest/StartupTest.cs @@ -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(); + } + } +} diff --git a/HttpClientStudy.UnitTest/startup.cs b/HttpClientStudy.UnitTest/startup.cs index 7497001..efa6bb9 100644 --- a/HttpClientStudy.UnitTest/startup.cs +++ b/HttpClientStudy.UnitTest/startup.cs @@ -25,7 +25,7 @@ namespace HttpClientStudy.UnitTest /// public IHostBuilder CreateHostBuilder() { - return Host.CreateDefaultBuilder() ; + return Host.CreateDefaultBuilder(); } /// @@ -34,16 +34,19 @@ namespace HttpClientStudy.UnitTest /// public void ConfigureHost(IHostBuilder hostBuilder) { + //确保启动webapi项目 + StartWebApiProject(); + hostBuilder //主机配置 - .ConfigureHostConfiguration(builder => + .ConfigureHostConfiguration(builder => { }) //应用配置 - .ConfigureAppConfiguration((context, builder) => - { - + .ConfigureAppConfiguration((context, builder) => + { + }); hostBuilder.ConfigureWebHost(webHostBuilder => @@ -71,9 +74,9 @@ namespace HttpClientStudy.UnitTest /// 注册服务:必须 /// /// - 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 @@ -81,9 +84,56 @@ namespace HttpClientStudy.UnitTest public void ConfigureServices(IServiceCollection services) => services.AddLogging(lb => lb.AddXunitOutput()); public void Configure(IApplicationBuilder app) - { + { app.Run(static context => context.Response.WriteAsync("xxxxxx")); - } + } + } + + /// + /// 启动webapi项目 + /// (出现webapi项目启动命令行窗口) + /// + 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; + } + } } } diff --git a/HttpClientStudy.WebApp/Controllers/ErrorDemoController.cs b/HttpClientStudy.WebApp/Controllers/ErrorDemoController.cs index 7f4e212..63f4536 100644 --- a/HttpClientStudy.WebApp/Controllers/ErrorDemoController.cs +++ b/HttpClientStudy.WebApp/Controllers/ErrorDemoController.cs @@ -35,9 +35,6 @@ namespace HttpClientStudy.WebApp.Controllers public IActionResult Error500() { throw new System.Exception("服务器异常"); - - var result = BaseResultUtil.Success("服务器异常"); - return new JsonResult(result); } } } diff --git a/HttpClientStudy.WebApp/Program.cs b/HttpClientStudy.WebApp/Program.cs index 1f237c7..b1ee07d 100644 --- a/HttpClientStudy.WebApp/Program.cs +++ b/HttpClientStudy.WebApp/Program.cs @@ -1,8 +1,8 @@ using System.Text; - -using HttpClientStudy.Model; -using HttpClientStudy.Service; +using System.Diagnostics; +using System.Threading ; +using System.Collections.Generic; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Http.Features; @@ -10,6 +10,10 @@ using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; +using HttpClientStudy.Model; +using HttpClientStudy.Service; +using HttpClientStudy.Config; + namespace HttpClientStudy.WebApp { /// @@ -33,7 +37,7 @@ namespace HttpClientStudy.WebApp builder.Services.AddDistributedMemoryCache(); //Session - builder.Services.AddSession(option => + builder.Services.AddSession(option => { option.Cookie.Name = "HttpClientStudy"; option.IOTimeout = TimeSpan.FromHours(1); @@ -41,7 +45,7 @@ namespace HttpClientStudy.WebApp }); //Kestrelѡ - builder.Services.Configure( option => + builder.Services.Configure(option => { //ASP.NET Core 3.0 ֮ǰİ汾AllowSynchronousIO Ĭǿ // true ͬ IO ,Getе.ֱֻӴжȡԶģͰ󶨡 @@ -49,7 +53,7 @@ namespace HttpClientStudy.WebApp }); //Formύѡ - builder.Services.Configure(options => + builder.Services.Configure(options => { //options.BufferBody = true; options.MultipartBodyLengthLimit = long.MaxValue; @@ -116,11 +120,11 @@ namespace HttpClientStudy.WebApp }); //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 var app = builder.Build(); - + #region Httpܵ //ʱͳм