From 0786050265153041e86330c16eaf9ee93c0389f6 Mon Sep 17 00:00:00 2001 From: wanggaofeng <15601716045@163.com> Date: Wed, 22 May 2024 20:55:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Docs/1.1.概述.ipynb | 92 ++++++++++++++ Docs/1.2.使用原则.ipynb | 58 +++++++++ HttpClientStudy.Core/GlobalUsings.cs | 1 + ...{SimpleHttpClient.cs => BaseHttpClient.cs} | 2 +- HttpClientStudy.Core/HttpError.cs | 5 +- HttpClientStudy.Core/Utils/StartupUtility.cs | 113 ++++++++++++++++++ .../Fixtures/AppCollectionFixture.cs | 14 +++ .../Fixtures/AppFixture.cs | 21 ++++ .../HttpClientStudy.UnitTest.csproj | 4 - ...ttpClientTest.cs => BaseHttpClientTest.cs} | 8 +- .../HttpResponses/HttpResponseContentTest.cs | 8 -- HttpClientStudy.UnitTest/StartupTest.cs | 19 --- HttpClientStudy.UnitTest/startup.cs | 93 +++----------- HttpClientStudy.WebClient/Program.cs | 36 ++++++ 14 files changed, 361 insertions(+), 113 deletions(-) create mode 100644 Docs/1.1.概述.ipynb create mode 100644 Docs/1.2.使用原则.ipynb rename HttpClientStudy.Core/HttpClients/{SimpleHttpClient.cs => BaseHttpClient.cs} (98%) create mode 100644 HttpClientStudy.Core/Utils/StartupUtility.cs create mode 100644 HttpClientStudy.UnitTest/Fixtures/AppCollectionFixture.cs create mode 100644 HttpClientStudy.UnitTest/Fixtures/AppFixture.cs rename HttpClientStudy.UnitTest/HttpClients/{SimpleHttpClientTest.cs => BaseHttpClientTest.cs} (81%) delete mode 100644 HttpClientStudy.UnitTest/StartupTest.cs diff --git a/Docs/1.1.概述.ipynb b/Docs/1.1.概述.ipynb new file mode 100644 index 0000000..92f29e9 --- /dev/null +++ b/Docs/1.1.概述.ipynb @@ -0,0 +1,92 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "source": [ + "## HttpClient 概述" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 作用" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## 整体理解" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 前世今生" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + }, + "vscode": { + "languageId": "polyglot-notebook" + } + }, + "source": [ + "## 架构图" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 相关资源" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".NET (C#)", + "language": "C#", + "name": ".net-csharp" + }, + "language_info": { + "name": "python" + }, + "polyglot_notebook": { + "kernelInfo": { + "defaultKernelName": "csharp", + "items": [ + { + "aliases": [], + "name": "csharp" + } + ] + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Docs/1.2.使用原则.ipynb b/Docs/1.2.使用原则.ipynb new file mode 100644 index 0000000..7656438 --- /dev/null +++ b/Docs/1.2.使用原则.ipynb @@ -0,0 +1,58 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "source": [ + "# HttpClient 使用原则" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + }, + "vscode": { + "languageId": "polyglot-notebook" + } + }, + "source": [ + "## 1、复用" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".NET (C#)", + "language": "C#", + "name": ".net-csharp" + }, + "language_info": { + "name": "python" + }, + "polyglot_notebook": { + "kernelInfo": { + "defaultKernelName": "csharp", + "items": [ + { + "aliases": [], + "name": "csharp" + } + ] + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/HttpClientStudy.Core/GlobalUsings.cs b/HttpClientStudy.Core/GlobalUsings.cs index 803bacb..25ab24c 100644 --- a/HttpClientStudy.Core/GlobalUsings.cs +++ b/HttpClientStudy.Core/GlobalUsings.cs @@ -11,6 +11,7 @@ global using System.Net.Http; global using System.Net.Http.Json; global using System.Net.Http.Headers; +global using HttpClientStudy.Config; global using HttpClientStudy.Model; global using HttpClientStudy.Core; diff --git a/HttpClientStudy.Core/HttpClients/SimpleHttpClient.cs b/HttpClientStudy.Core/HttpClients/BaseHttpClient.cs similarity index 98% rename from HttpClientStudy.Core/HttpClients/SimpleHttpClient.cs rename to HttpClientStudy.Core/HttpClients/BaseHttpClient.cs index 5818b6b..4788c0e 100644 --- a/HttpClientStudy.Core/HttpClients/SimpleHttpClient.cs +++ b/HttpClientStudy.Core/HttpClients/BaseHttpClient.cs @@ -3,7 +3,7 @@ /// /// 简单 HttpClient 包装类 /// - public class SimpleHttpClient + public class BaseHttpClient { #region Get请求 public string Get(string url) diff --git a/HttpClientStudy.Core/HttpError.cs b/HttpClientStudy.Core/HttpError.cs index abff74f..72ea0ed 100644 --- a/HttpClientStudy.Core/HttpError.cs +++ b/HttpClientStudy.Core/HttpError.cs @@ -30,11 +30,11 @@ namespace HttpClientStudy.Core /// /// /// - /// 简化处理 + /// 错误处理 /// public class HttpError { - // 定义一个 HttpClient 实例,共享 + // 定义一个 HttpClient 共享实例 public static HttpClient HttpClient = new HttpClient(new SocketsHttpHandler() { PooledConnectionLifetime = TimeSpan.FromMinutes(1) }) { BaseAddress = new Uri(WebApiConfigManager.GetWebApiConfig().BaseUrl) @@ -61,7 +61,6 @@ namespace HttpClientStudy.Core { var response = await HttpClient.GetAsync("http://localhost:30"); } - catch (Exception ex) { // 捕获异常,处理 diff --git a/HttpClientStudy.Core/Utils/StartupUtility.cs b/HttpClientStudy.Core/Utils/StartupUtility.cs new file mode 100644 index 0000000..53c8269 --- /dev/null +++ b/HttpClientStudy.Core/Utils/StartupUtility.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HttpClientStudy.Core.Utils +{ + /// + /// 启动工具类 + /// + public static class StartupUtility + { + /// + /// 启动webapi项目 + /// (出现webapi项目启动命令行窗口) + /// + public static 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 System.Diagnostics.ProcessStartInfo("dotnet", $"run --project {webApiProjectPath}") + { + UseShellExecute = true, + CreateNoWindow = false, + RedirectStandardOutput = false + }; + + //启动 + System.Diagnostics.Process.Start(prossInfo); + } + + //由进程名判断 + //bool webAppIsRunningByProcessName() + //{ + // return Process.GetProcessesByName(projectAndMutexName).ToList().Count == 0; + //} + + //由互斥锁判断 + bool webAppIsRunningByMutex() + { + bool createdResult = true; + + //创建互斥锁 + using (var mutex = new Mutex(true, projectAndMutexName, out createdResult)) + { + if (createdResult) + { + mutex.ReleaseMutex(); + } + } + + //互斥锁是否创建成功 + return !createdResult; + } + + } + + /// + /// 关闭webapi项目 + /// (出现webapi项目启动命令行窗口) + /// + public static void ExitWebApiProject() + { + string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName; + + //webapi为运行状态则关闭 + if (webAppIsRunningByMutex()) + { + var webApiProcess = System.Diagnostics.Process.GetProcessesByName(projectAndMutexName); + + if (webApiProcess != null && webApiProcess.Length>0) + { + webApiProcess[0].Kill(); + } + } + + //由进程名判断 + //bool webAppIsRunningByProcessName() + //{ + // return Process.GetProcessesByName(projectAndMutexName).ToList().Count == 0; + //} + + //由互斥锁判断 + bool webAppIsRunningByMutex() + { + bool createdResult = true; + + //创建互斥锁 + using (var mutex = new Mutex(true, projectAndMutexName, out createdResult)) + { + if (createdResult) + { + mutex.ReleaseMutex(); + } + } + + //互斥锁是否创建成功 + return !createdResult; + } + } + } +} diff --git a/HttpClientStudy.UnitTest/Fixtures/AppCollectionFixture.cs b/HttpClientStudy.UnitTest/Fixtures/AppCollectionFixture.cs new file mode 100644 index 0000000..c7e8896 --- /dev/null +++ b/HttpClientStudy.UnitTest/Fixtures/AppCollectionFixture.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HttpClientStudy.UnitTest.Fixtures +{ + [CollectionDefinition("App")] + public class AppCollectionFixture : ICollectionFixture + { + + } +} diff --git a/HttpClientStudy.UnitTest/Fixtures/AppFixture.cs b/HttpClientStudy.UnitTest/Fixtures/AppFixture.cs new file mode 100644 index 0000000..ee25f35 --- /dev/null +++ b/HttpClientStudy.UnitTest/Fixtures/AppFixture.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HttpClientStudy.UnitTest.Fixtures +{ + public class AppFixture : IDisposable + { + public AppFixture() + { + + } + + public void Dispose() + { + + } + } +} diff --git a/HttpClientStudy.UnitTest/HttpClientStudy.UnitTest.csproj b/HttpClientStudy.UnitTest/HttpClientStudy.UnitTest.csproj index 5c28ef6..47091ea 100644 --- a/HttpClientStudy.UnitTest/HttpClientStudy.UnitTest.csproj +++ b/HttpClientStudy.UnitTest/HttpClientStudy.UnitTest.csproj @@ -43,8 +43,4 @@ - - - - diff --git a/HttpClientStudy.UnitTest/HttpClients/SimpleHttpClientTest.cs b/HttpClientStudy.UnitTest/HttpClients/BaseHttpClientTest.cs similarity index 81% rename from HttpClientStudy.UnitTest/HttpClients/SimpleHttpClientTest.cs rename to HttpClientStudy.UnitTest/HttpClients/BaseHttpClientTest.cs index bafefdc..6cf23ab 100644 --- a/HttpClientStudy.UnitTest/HttpClients/SimpleHttpClientTest.cs +++ b/HttpClientStudy.UnitTest/HttpClients/BaseHttpClientTest.cs @@ -3,10 +3,10 @@ /// /// SimpleHttpClient 测试类 /// - public class SimpleHttpClientTest + public class BaseHttpClientTest { private readonly ITestOutputHelper _logger; - public SimpleHttpClientTest(ITestOutputHelper outputHelper) + public BaseHttpClientTest(ITestOutputHelper outputHelper) { _logger = outputHelper; } @@ -14,7 +14,7 @@ [Fact] public void Get_Test() { - SimpleHttpClient client = new SimpleHttpClient(); + BaseHttpClient client = new BaseHttpClient(); var result = client.Get(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/Simple/GetAccount"); @@ -25,7 +25,7 @@ [Fact] public void GetJson_Test() { - SimpleHttpClient client = new SimpleHttpClient(); + BaseHttpClient client = new BaseHttpClient(); var result = client.GetJson>(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/Simple/GetAccount"); diff --git a/HttpClientStudy.UnitTest/HttpResponses/HttpResponseContentTest.cs b/HttpClientStudy.UnitTest/HttpResponses/HttpResponseContentTest.cs index 3f40552..3ade0e0 100644 --- a/HttpClientStudy.UnitTest/HttpResponses/HttpResponseContentTest.cs +++ b/HttpClientStudy.UnitTest/HttpResponses/HttpResponseContentTest.cs @@ -24,14 +24,6 @@ namespace HttpClientStudy.UnitTest.HttpResponses client.PostAsync("http://www.baidu.com", content); } - - [Fact] - public async void Test2() - { - HttpClient client = new HttpClient(); - - var dd = await client.PostAsJsonAsync("url", new { Name = "" }, CancellationToken.None); - } } public class Demo diff --git a/HttpClientStudy.UnitTest/StartupTest.cs b/HttpClientStudy.UnitTest/StartupTest.cs deleted file mode 100644 index 24b2464..0000000 --- a/HttpClientStudy.UnitTest/StartupTest.cs +++ /dev/null @@ -1,19 +0,0 @@ -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() - { - - } - } -} diff --git a/HttpClientStudy.UnitTest/startup.cs b/HttpClientStudy.UnitTest/startup.cs index e29deff..04b9ae9 100644 --- a/HttpClientStudy.UnitTest/startup.cs +++ b/HttpClientStudy.UnitTest/startup.cs @@ -1,5 +1,7 @@ using System.Diagnostics; +using HttpClientStudy.Core.Utils; + using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; @@ -41,18 +43,18 @@ namespace HttpClientStudy.UnitTest public void ConfigureHost(IHostBuilder hostBuilder) { //确保启动 webapi 项目 - StartWebApiProject(); + StartupUtility.StartWebApiProject(); hostBuilder - //主机配置 + //主机配置设置 .ConfigureHostConfiguration(builder => { }) - //应用配置 + //应用配置设置 .ConfigureAppConfiguration((context, builder) => { - + }) //配置Web主机 .ConfigureWebHost(webHostBuilder => @@ -65,21 +67,16 @@ namespace HttpClientStudy.UnitTest }) .ConfigureTestServices(a => { - + Console.WriteLine("+++++++++++++++++++++++++++++++++"); + + a.BuildServiceProvider().GetRequiredService().ApplicationStopping.Register(() => + { + Console.WriteLine("========================="); + }); + }) - .UseStartup(); - - //配置默认配置项 - //webHostBuilder.ConfigureAppConfiguration((context, configBuilder) => - //{ - // configBuilder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); - // configBuilder.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true); - //}); - - //webHostBuilder.ConfigureServices(services => - //{ - // services.AddHealthChecks(); - //}); + .UseStartup() + ; }); } @@ -89,62 +86,10 @@ namespace HttpClientStudy.UnitTest /// public void ConfigureServices(IServiceCollection services, HostBuilderContext context) { - Debugger.Log(1, "DI", "ConfigureServices"); - } - - /// - /// 启动webapi项目 - /// (出现webapi项目启动命令行窗口) - /// - private 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() + services.BuildServiceProvider().GetRequiredService().ApplicationStopping.Register(() => { - bool createdResult = true; - - //创建互斥锁 - using (var mutex = new Mutex(true, projectAndMutexName, out createdResult)) - { - if (createdResult) - { - mutex.ReleaseMutex(); - } - } - - //互斥锁是否创建成功 - return !createdResult; - } - + Console.WriteLine("========================="); + }); } private class WebApiStartup @@ -156,7 +101,7 @@ namespace HttpClientStudy.UnitTest public void Configure(IApplicationBuilder app) { - app.Run(static context => context.Response.WriteAsync("xxxxxx")); + } } } diff --git a/HttpClientStudy.WebClient/Program.cs b/HttpClientStudy.WebClient/Program.cs index df2434c..f791495 100644 --- a/HttpClientStudy.WebClient/Program.cs +++ b/HttpClientStudy.WebClient/Program.cs @@ -1,3 +1,7 @@ +using System.Diagnostics; + +using HttpClientStudy.Core.Utils; + var builder = WebApplication.CreateBuilder(args); // Add services to the container. @@ -20,4 +24,36 @@ app.UseAuthorization(); app.MapControllers(); +Process currentProcess = Process.GetCurrentProcess(); +currentProcess.EnableRaisingEvents = true; +currentProcess.Exited += (s, r) => +{ + Console.WriteLine("000000000000000000000000000000000000"); +}; + + +// ȡ IHostApplicationLifetime ʵ +var applicationLifetime = app.Services.GetRequiredService(); + +// עӦóر¼ +applicationLifetime.ApplicationStopping.Register(() => +{ + //رWebApi + StartupUtility.ExitWebApiProject(); +}); + +applicationLifetime.ApplicationStopped.Register(() => { + Console.WriteLine("xxxxxxxxxxxxxxxxxxxx"); +}); + +// ע AppDomain δ쳣¼ +AppDomain.CurrentDomain.UnhandledException += (s,e)=> +{ + Console.WriteLine("˳"); +}; + + +//ȷWebApi +StartupUtility.StartWebApiProject(); + app.Run();