add: WebApplication控制服务

This commit is contained in:
jackfiled 2024-01-20 12:26:30 +08:00
parent cc3e7f1e4b
commit 71b4549ce4
6 changed files with 123 additions and 4 deletions

View File

@ -2,5 +2,5 @@
public class BlogApplicationOptions
{
public string[]? Args { get; init; }
public required string[] Args { get; init; }
}

View File

@ -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

View File

@ -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<EssayScanService>();
builder.Services.AddSingleton<RendererService>();
builder.Services.AddSingleton<EssayContentService>();
}
return builder;
public static void ConfigureWebApplication(this BlogApplicationBuilder builder,
Action<WebApplicationBuilder> configureWebApplicationBuilder,
Action<WebApplication> configureWebApplication)
{
builder.Services.AddHostedService<WebApplicationHostedService>(provider =>
new WebApplicationHostedService(configureWebApplicationBuilder,
configureWebApplication, provider));
}
}

View File

@ -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<WebApplication> _configureWebApplication;
private Website? _currentWebsite;
public WebApplicationHostedService(Action<WebApplicationBuilder> configureWebApplicationBuilder,
Action<WebApplication> 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<IHostLifetime>();
_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<EssayContentService>(_ =>
provider.GetRequiredService<EssayContentService>());
}
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;
}
}
}

View File

@ -11,6 +11,10 @@
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Markdig" Version="0.34.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.0" />

View File

@ -1 +0,0 @@
@using Microsoft.AspNetCore.Components.Web