From 71b4549ce479a625efde9dc7a1af1fe0c06b8a4f Mon Sep 17 00:00:00 2001 From: jackfiled Date: Sat, 20 Jan 2024 12:26:30 +0800 Subject: [PATCH] =?UTF-8?q?add:=20WebApplication=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Builder/BlogApplicationOptions.cs | 2 +- YaeBlog.Core/Components/_Imports.razor | 8 ++ .../Extensions/BlogApplicationExtension.cs | 12 ++- .../Services/WebApplicationHostedService.cs | 100 ++++++++++++++++++ YaeBlog.Core/YaeBlog.Core.csproj | 4 + YaeBlog.Core/_Imports.razor | 1 - 6 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 YaeBlog.Core/Components/_Imports.razor create mode 100644 YaeBlog.Core/Services/WebApplicationHostedService.cs delete mode 100644 YaeBlog.Core/_Imports.razor diff --git a/YaeBlog.Core/Builder/BlogApplicationOptions.cs b/YaeBlog.Core/Builder/BlogApplicationOptions.cs index b1f87af..c2240d6 100644 --- a/YaeBlog.Core/Builder/BlogApplicationOptions.cs +++ b/YaeBlog.Core/Builder/BlogApplicationOptions.cs @@ -2,5 +2,5 @@ public class BlogApplicationOptions { - public string[]? Args { get; init; } + public required string[] Args { get; init; } } diff --git a/YaeBlog.Core/Components/_Imports.razor b/YaeBlog.Core/Components/_Imports.razor new file mode 100644 index 0000000..d88eed9 --- /dev/null +++ b/YaeBlog.Core/Components/_Imports.razor @@ -0,0 +1,8 @@ +@using System.Net.Http +@using System.Net.Http.Json +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using static Microsoft.AspNetCore.Components.Web.RenderMode +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop diff --git a/YaeBlog.Core/Extensions/BlogApplicationExtension.cs b/YaeBlog.Core/Extensions/BlogApplicationExtension.cs index eaf1507..3b75ac6 100644 --- a/YaeBlog.Core/Extensions/BlogApplicationExtension.cs +++ b/YaeBlog.Core/Extensions/BlogApplicationExtension.cs @@ -1,4 +1,5 @@ using Markdig; +using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using YaeBlog.Core.Builder; @@ -11,7 +12,7 @@ namespace YaeBlog.Core.Extensions; internal static class BlogApplicationExtension { - public static BlogApplicationBuilder ConfigureBlogApplication(this BlogApplicationBuilder builder) + public static void ConfigureBlogApplication(this BlogApplicationBuilder builder) { builder.Configuration.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", @@ -33,7 +34,14 @@ internal static class BlogApplicationExtension builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); + } - return builder; + public static void ConfigureWebApplication(this BlogApplicationBuilder builder, + Action configureWebApplicationBuilder, + Action configureWebApplication) + { + builder.Services.AddHostedService(provider => + new WebApplicationHostedService(configureWebApplicationBuilder, + configureWebApplication, provider)); } } diff --git a/YaeBlog.Core/Services/WebApplicationHostedService.cs b/YaeBlog.Core/Services/WebApplicationHostedService.cs new file mode 100644 index 0000000..919804c --- /dev/null +++ b/YaeBlog.Core/Services/WebApplicationHostedService.cs @@ -0,0 +1,100 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace YaeBlog.Core.Services; + +public class WebApplicationHostedService : IHostedService +{ + private readonly WebApplicationBuilder _websiteBuilder = WebApplication.CreateBuilder(); + + private readonly Action _configureWebApplication; + + private Website? _currentWebsite; + + public WebApplicationHostedService(Action configureWebApplicationBuilder, + Action configureWebApplication, + IServiceProvider hostServiceProvider) + { + _configureWebApplication = configureWebApplication; + configureWebApplicationBuilder(_websiteBuilder); + AddHostServices(hostServiceProvider); + } + + public async Task BuildWebsite() + { + if (_currentWebsite is not null) + { + await _currentWebsite.ShutdownAsync(new CancellationToken()); + } + + WebApplication application = _websiteBuilder.Build(); + _configureWebApplication(application); + IHostLifetime websiteLifetime = application.Services.GetRequiredService(); + _currentWebsite = new Website(application, websiteLifetime); + } + + public Task RunAsync() + { + if (_currentWebsite is not null) + { + return _currentWebsite.RunAsync(); + } + + throw new InvalidOperationException("Website has not been built."); + } + + public Task ShutdownAsync() + { + if (_currentWebsite is { Running: true }) + { + return _currentWebsite.ShutdownAsync(new CancellationToken()); + } + + throw new InvalidOperationException("Website is not running."); + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + await BuildWebsite(); + _ = RunAsync(); + } + + public Task StopAsync(CancellationToken cancellationToken) + { + if (_currentWebsite is { Running: true }) + { + return _currentWebsite.ShutdownAsync(cancellationToken); + } + + return Task.CompletedTask; + } + + private void AddHostServices(IServiceProvider provider) + { + _websiteBuilder.Services.AddSingleton(_ => + provider.GetRequiredService()); + } + + + private class Website(WebApplication application, IHostLifetime websiteLifetime) + { + public bool Running { get; private set; } + + public Task RunAsync() + { + Running = true; + return application.RunAsync(); + } + + public async Task ShutdownAsync(CancellationToken cancellationToken) + { + if (!Running) + { + await websiteLifetime.StopAsync(cancellationToken); + } + + Running = false; + } + } +} diff --git a/YaeBlog.Core/YaeBlog.Core.csproj b/YaeBlog.Core/YaeBlog.Core.csproj index f588dac..e6d8669 100644 --- a/YaeBlog.Core/YaeBlog.Core.csproj +++ b/YaeBlog.Core/YaeBlog.Core.csproj @@ -10,6 +10,10 @@ + + + + diff --git a/YaeBlog.Core/_Imports.razor b/YaeBlog.Core/_Imports.razor deleted file mode 100644 index 7728512..0000000 --- a/YaeBlog.Core/_Imports.razor +++ /dev/null @@ -1 +0,0 @@ -@using Microsoft.AspNetCore.Components.Web