133 lines
5.9 KiB
C#
133 lines
5.9 KiB
C#
using System;
|
|||
|
|
using System.Threading.Tasks;
|
||
|
|
using PCL.Core.Logging;
|
||
|
|
|
||
|
|
namespace PCL.Core.App.IoC;
|
||
|
|
|
||
|
|
partial class Lifecycle
|
||
|
|
{
|
||
|
|
private class SystemLifecycleService : ILifecycleService
|
||
|
|
{
|
||
|
|
public string Name => "系统";
|
||
|
|
public string Identifier => "system";
|
||
|
|
public bool SupportAsync => false;
|
||
|
|
public Task StartAsync() => Task.CompletedTask;
|
||
|
|
public Task StopAsync() => Task.CompletedTask;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static readonly ILifecycleService _SystemService = new SystemLifecycleService();
|
||
|
|
private static readonly LifecycleServiceInfo _SystemServiceInfo = new(_SystemService, LifecycleState.BeforeLoading);
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 系统默认上下文,无特殊需求请勿使用。
|
||
|
|
/// </summary>
|
||
|
|
internal static readonly LifecycleContext SystemContext = GetContext(_SystemService);
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 获取指定服务项对应的上下文实例用于日志输出、多任务通信等。一般情况下只推荐获取自身上下文。
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="self">服务项实例</param>
|
||
|
|
/// <returns>上下文实例</returns>
|
||
|
|
public static LifecycleContext GetContext(ILifecycleService self) => new(
|
||
|
|
service: self,
|
||
|
|
onLog: item =>
|
||
|
|
{
|
||
|
|
lock (_PendingLogs)
|
||
|
|
{
|
||
|
|
if (_logService is null) _PendingLogs.Add(item);
|
||
|
|
else _PushLog(item, _logService);
|
||
|
|
}
|
||
|
|
if (item.ActionLevel == ActionLevel.MsgBoxFatal) _FatalExit();
|
||
|
|
},
|
||
|
|
onRequestExit: statusCode =>
|
||
|
|
{
|
||
|
|
if (CurrentState != LifecycleState.BeforeLoading)
|
||
|
|
throw new InvalidOperationException("只能在 BeforeLoading 时请求退出");
|
||
|
|
Context.Info($"{_ServiceName(self)} 已请求退出程序");
|
||
|
|
_Exit(statusCode);
|
||
|
|
},
|
||
|
|
onRequestRestart: args =>
|
||
|
|
{
|
||
|
|
_hasRequestedRestart = true;
|
||
|
|
_requestRestartService = self;
|
||
|
|
_requestRestartArguments = args;
|
||
|
|
},
|
||
|
|
onDeclareStopped: () =>
|
||
|
|
{
|
||
|
|
var identifier = self.Identifier;
|
||
|
|
if (GetServiceInfo(identifier)?.Identifier == identifier)
|
||
|
|
throw new InvalidOperationException("只能在服务启动阶段调用");
|
||
|
|
_DeclaredStoppedServices.Add(self);
|
||
|
|
},
|
||
|
|
onRequestStopLoading: () =>
|
||
|
|
{
|
||
|
|
if (CurrentState != LifecycleState.BeforeLoading)
|
||
|
|
throw new InvalidOperationException("只能在 BeforeLoading 时请求停止加载");
|
||
|
|
Context.Info($"{_ServiceName(self)} 已请求停止继续加载");
|
||
|
|
_hasRequestedStopLoading = true;
|
||
|
|
}
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 若要获取服务项自身的上下文实例,请使用 <see cref="Lifecycle.GetContext"/> 。
|
||
|
|
/// </summary>
|
||
|
|
public class LifecycleContext(
|
||
|
|
ILifecycleService service,
|
||
|
|
Action<LifecycleLogItem> onLog,
|
||
|
|
Action<int> onRequestExit,
|
||
|
|
Action<string?> onRequestRestart,
|
||
|
|
Action onDeclareStopped,
|
||
|
|
Action onRequestStopLoading)
|
||
|
|
{
|
||
|
|
#region 日志输出
|
||
|
|
|
||
|
|
public void CustomLog(
|
||
|
|
string message,
|
||
|
|
Exception? ex = null,
|
||
|
|
LogLevel level = LogLevel.Trace,
|
||
|
|
ActionLevel? actionLevel = null
|
||
|
|
) => onLog(new LifecycleLogItem(service, message, ex, level, actionLevel ?? level.DefaultActionLevel()));
|
||
|
|
|
||
|
|
public void Trace(string message, Exception? ex = null, ActionLevel? actionLevel = null) => CustomLog(message, ex, LogLevel.Trace, actionLevel);
|
||
|
|
public void Debug(string message, Exception? ex = null, ActionLevel? actionLevel = null) => CustomLog(message, ex, LogLevel.Debug, actionLevel);
|
||
|
|
public void Info(string message, Exception? ex = null, ActionLevel? actionLevel = null) => CustomLog(message, ex, LogLevel.Info, actionLevel);
|
||
|
|
public void Warn(string message, Exception? ex = null, ActionLevel? actionLevel = null) => CustomLog(message, ex, LogLevel.Warning, actionLevel);
|
||
|
|
public void Error(string message, Exception? ex = null, ActionLevel? actionLevel = null) => CustomLog(message, ex, LogLevel.Error, actionLevel);
|
||
|
|
public void Fatal(string message, Exception? ex = null, ActionLevel? actionLevel = null) => CustomLog(message, ex, LogLevel.Fatal, actionLevel);
|
||
|
|
|
||
|
|
#endregion
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 服务项自身实例。
|
||
|
|
/// </summary>
|
||
|
|
public ILifecycleService ServiceInstance => service;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 请求退出程序。仅可在 <see cref="LifecycleState.BeforeLoading"/> 状态调用。
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="statusCode">程序返回的状态码</param>
|
||
|
|
/// <exception cref="InvalidOperationException">尝试在非 <see cref="LifecycleState.BeforeLoading"/> 状态调用</exception>
|
||
|
|
public void RequestExit(int statusCode = 0) => onRequestExit(statusCode);
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 请求在程序退出时重启。调用该方法后,程序将在正常退出流程中自动执行重启,通常与退出程序结合使用。
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="arguments">重启进程时使用的命令行参数</param>
|
||
|
|
public void RequestRestartOnExit(string? arguments = null) => onRequestRestart(arguments);
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 标记自身已经结束运行。调用该方法将会直接从正在运行列表中移除该服务项,后续的
|
||
|
|
/// <c>Stop</c> 等均不会触发。仅可在服务启动阶段即 <c>Start</c> 方法结束前调用。
|
||
|
|
/// </summary>
|
||
|
|
/// <exception cref="InvalidOperationException">尝试在非启动阶段调用</exception>
|
||
|
|
public void DeclareStopped() => onDeclareStopped();
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 请求停止继续加载。多用于初始阶段在非 STA 线程中运行的服务接管进程整个生命周期,仅可在
|
||
|
|
/// <see cref="LifecycleState.BeforeLoading"/> 状态调用。
|
||
|
|
/// </summary>
|
||
|
|
/// <exception cref="InvalidOperationException">尝试在非 <see cref="LifecycleState.BeforeLoading"/> 状态调用</exception>
|
||
|
|
public void RequestStopLoading() => onRequestStopLoading();
|
||
|
|
}
|