mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-07 00:39:00 +08:00
326 lines
11 KiB
C#
326 lines
11 KiB
C#
// Copyright (c) 2025-2026 GeWuYou
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
using GFramework.Core.Abstractions.Architectures;
|
|
using GFramework.Core.Abstractions.Enums;
|
|
using GFramework.Core.Abstractions.Lifecycle;
|
|
using GFramework.Core.Abstractions.Logging;
|
|
using GFramework.Core.Abstractions.Model;
|
|
using GFramework.Core.Abstractions.Systems;
|
|
using GFramework.Core.Abstractions.Utility;
|
|
|
|
namespace GFramework.Core.Architectures;
|
|
|
|
/// <summary>
|
|
/// 架构生命周期管理器
|
|
/// 负责管理架构的阶段转换、组件初始化和销毁
|
|
/// </summary>
|
|
internal sealed class ArchitectureLifecycle(
|
|
IArchitecture architecture,
|
|
IArchitectureConfiguration configuration,
|
|
IArchitectureServices services,
|
|
ILogger logger)
|
|
{
|
|
#region Lifecycle Hook Management
|
|
|
|
/// <summary>
|
|
/// 注册生命周期钩子
|
|
/// </summary>
|
|
/// <param name="hook">生命周期钩子实例</param>
|
|
/// <returns>注册的钩子实例</returns>
|
|
public IArchitectureLifecycleHook RegisterLifecycleHook(IArchitectureLifecycleHook hook)
|
|
{
|
|
return _phaseCoordinator.RegisterLifecycleHook(hook);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Component Lifecycle Management
|
|
|
|
/// <summary>
|
|
/// 统一的组件生命周期注册逻辑
|
|
/// </summary>
|
|
/// <param name="component">要注册的组件</param>
|
|
public void RegisterLifecycleComponent(object component)
|
|
{
|
|
if (component is IInitializable initializable)
|
|
{
|
|
if (_initialized)
|
|
{
|
|
if (!configuration.ArchitectureProperties.AllowLateRegistration)
|
|
throw new InvalidOperationException("Cannot initialize component after Architecture is Ready");
|
|
|
|
InitializeLateRegisteredComponent(initializable);
|
|
}
|
|
|
|
else if (_pendingInitializableSet.Add(initializable))
|
|
{
|
|
_pendingInitializableList.Add(initializable);
|
|
logger.Trace($"Added {component.GetType().Name} to pending initialization queue");
|
|
}
|
|
}
|
|
|
|
_disposer.Register(component);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Phase Management
|
|
|
|
/// <summary>
|
|
/// 进入指定的架构阶段,并执行相应的生命周期管理操作
|
|
/// </summary>
|
|
/// <param name="next">要进入的下一个架构阶段</param>
|
|
public void EnterPhase(ArchitecturePhase next)
|
|
{
|
|
_phaseCoordinator.EnterPhase(next);
|
|
PhaseChanged?.Invoke(this, new ArchitecturePhaseChangedEventArgs(next));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Fields
|
|
|
|
private readonly TaskCompletionSource _readyTcs = new(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
|
|
/// <summary>
|
|
/// 待初始化组件的去重集合
|
|
/// </summary>
|
|
private readonly HashSet<IInitializable> _pendingInitializableSet = [];
|
|
|
|
/// <summary>
|
|
/// 存储所有待初始化的组件(统一管理,保持注册顺序)
|
|
/// </summary>
|
|
private readonly List<IInitializable> _pendingInitializableList = [];
|
|
|
|
/// <summary>
|
|
/// 架构阶段协调器
|
|
/// </summary>
|
|
private readonly ArchitecturePhaseCoordinator _phaseCoordinator =
|
|
new(architecture, configuration, services, logger);
|
|
|
|
/// <summary>
|
|
/// 架构销毁协调器
|
|
/// </summary>
|
|
private readonly ArchitectureDisposer _disposer = new(services, logger);
|
|
|
|
/// <summary>
|
|
/// 标记架构是否已初始化完成
|
|
/// </summary>
|
|
private bool _initialized;
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
/// <summary>
|
|
/// 当前架构的阶段
|
|
/// </summary>
|
|
public ArchitecturePhase CurrentPhase => _phaseCoordinator.CurrentPhase;
|
|
|
|
/// <summary>
|
|
/// 获取一个布尔值,指示当前架构是否处于就绪状态
|
|
/// </summary>
|
|
public bool IsReady => CurrentPhase == ArchitecturePhase.Ready;
|
|
|
|
/// <summary>
|
|
/// 获取一个布尔值,指示架构是否已初始化
|
|
/// </summary>
|
|
public bool IsInitialized => _initialized;
|
|
|
|
/// <summary>
|
|
/// 阶段变更事件(用于测试和扩展)
|
|
/// </summary>
|
|
public event EventHandler<ArchitecturePhaseChangedEventArgs>? PhaseChanged;
|
|
|
|
#endregion
|
|
|
|
#region Initialization
|
|
|
|
/// <summary>
|
|
/// 初始化所有待初始化的组件
|
|
/// </summary>
|
|
/// <param name="asyncMode">是否使用异步模式</param>
|
|
public async Task InitializeAllComponentsAsync(bool asyncMode)
|
|
{
|
|
logger.Info($"Initializing {_pendingInitializableList.Count} components");
|
|
|
|
var initializationPlan = CreateInitializationPlan();
|
|
|
|
await InitializePhaseComponentsAsync(
|
|
initializationPlan.Utilities,
|
|
ArchitecturePhase.BeforeUtilityInit,
|
|
ArchitecturePhase.AfterUtilityInit,
|
|
"context utilities",
|
|
"utility",
|
|
asyncMode)
|
|
.ConfigureAwait(false);
|
|
await InitializePhaseComponentsAsync(
|
|
initializationPlan.Models,
|
|
ArchitecturePhase.BeforeModelInit,
|
|
ArchitecturePhase.AfterModelInit,
|
|
"models",
|
|
"model",
|
|
asyncMode)
|
|
.ConfigureAwait(false);
|
|
await InitializePhaseComponentsAsync(
|
|
initializationPlan.Systems,
|
|
ArchitecturePhase.BeforeSystemInit,
|
|
ArchitecturePhase.AfterSystemInit,
|
|
"systems",
|
|
"system",
|
|
asyncMode)
|
|
.ConfigureAwait(false);
|
|
|
|
MarkInitializationCompleted();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步初始化单个组件
|
|
/// </summary>
|
|
/// <param name="component">要初始化的组件</param>
|
|
/// <param name="asyncMode">是否使用异步模式</param>
|
|
private static async Task InitializeComponentAsync(IInitializable component, bool asyncMode)
|
|
{
|
|
if (asyncMode && component is IAsyncInitializable asyncInit)
|
|
await asyncInit.InitializeAsync().ConfigureAwait(false);
|
|
else
|
|
component.Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 按架构既有阶段语义把待初始化组件拆分为 utility、model 和 system 三个批次。
|
|
/// 这样可以在压缩主流程复杂度的同时,继续复用注册顺序和接口类型决定的初始化分层。
|
|
/// </summary>
|
|
/// <returns>当前待初始化组件的阶段化批次。</returns>
|
|
private InitializationPlan CreateInitializationPlan()
|
|
{
|
|
return new InitializationPlan(
|
|
_pendingInitializableList.OfType<IContextUtility>().ToList(),
|
|
_pendingInitializableList.OfType<IModel>().ToList(),
|
|
_pendingInitializableList.OfType<ISystem>().ToList());
|
|
}
|
|
|
|
/// <summary>
|
|
/// 执行单个生命周期阶段的批量初始化,并统一维护阶段切换、日志输出和异步初始化策略。
|
|
/// </summary>
|
|
/// <typeparam name="TComponent">当前阶段要初始化的组件类型。</typeparam>
|
|
/// <param name="components">当前阶段的组件列表。</param>
|
|
/// <param name="beforePhase">阶段开始前要进入的生命周期状态。</param>
|
|
/// <param name="afterPhase">阶段结束后要进入的生命周期状态。</param>
|
|
/// <param name="componentGroupName">用于批量日志的组件组名称。</param>
|
|
/// <param name="componentLogName">用于单个组件日志的组件角色名称。</param>
|
|
/// <param name="asyncMode">是否允许优先走异步初始化契约。</param>
|
|
private async Task InitializePhaseComponentsAsync<TComponent>(
|
|
IReadOnlyList<TComponent> components,
|
|
ArchitecturePhase beforePhase,
|
|
ArchitecturePhase afterPhase,
|
|
string componentGroupName,
|
|
string componentLogName,
|
|
bool asyncMode)
|
|
where TComponent : class, IInitializable
|
|
{
|
|
EnterPhase(beforePhase);
|
|
|
|
if (components.Count != 0)
|
|
{
|
|
logger.Info($"Initializing {components.Count} {componentGroupName}");
|
|
|
|
foreach (var component in components)
|
|
{
|
|
logger.Debug($"Initializing {componentLogName}: {component.GetType().Name}");
|
|
await InitializeComponentAsync(component, asyncMode).ConfigureAwait(false);
|
|
}
|
|
|
|
logger.Info($"All {componentGroupName} initialized");
|
|
}
|
|
|
|
EnterPhase(afterPhase);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 在所有阶段初始化完成后清理挂起列表,并把生命周期状态切换到“已初始化”。
|
|
/// </summary>
|
|
private void MarkInitializationCompleted()
|
|
{
|
|
_pendingInitializableList.Clear();
|
|
_pendingInitializableSet.Clear();
|
|
_initialized = true;
|
|
logger.Info("All components initialized");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 立即初始化在常规初始化批次完成后新增的组件。
|
|
/// 当启用 <c>AllowLateRegistration</c> 时,生命周期层需要和注册层保持一致,
|
|
/// 让新增组件在注册当下完成同步初始化,而不是停留在未初始化状态。
|
|
/// </summary>
|
|
/// <param name="component">后注册的可初始化组件。</param>
|
|
private void InitializeLateRegisteredComponent(IInitializable component)
|
|
{
|
|
logger.Debug($"Initializing late-registered component: {component.GetType().Name}");
|
|
component.Initialize();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Destruction
|
|
|
|
/// <summary>
|
|
/// 异步销毁架构及所有组件
|
|
/// </summary>
|
|
public async ValueTask DestroyAsync()
|
|
{
|
|
await _disposer.DestroyAsync(CurrentPhase, EnterPhase).ConfigureAwait(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 销毁架构并清理所有组件资源(同步方法,保留用于向后兼容)
|
|
/// </summary>
|
|
[Obsolete("建议使用 DestroyAsync() 以支持异步清理")]
|
|
public void Destroy()
|
|
{
|
|
DestroyAsync().AsTask().GetAwaiter().GetResult();
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 保存一次完整初始化流程所需的三个阶段批次。
|
|
/// </summary>
|
|
/// <param name="Utilities">Utility 初始化批次。</param>
|
|
/// <param name="Models">Model 初始化批次。</param>
|
|
/// <param name="Systems">System 初始化批次。</param>
|
|
private readonly record struct InitializationPlan(
|
|
IReadOnlyList<IContextUtility> Utilities,
|
|
IReadOnlyList<IModel> Models,
|
|
IReadOnlyList<ISystem> Systems);
|
|
|
|
#region Ready State
|
|
|
|
/// <summary>
|
|
/// 标记架构为就绪状态
|
|
/// </summary>
|
|
public void MarkAsReady()
|
|
{
|
|
EnterPhase(ArchitecturePhase.Ready);
|
|
_readyTcs.TrySetResult();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 标记架构初始化失败
|
|
/// </summary>
|
|
/// <param name="exception">失败异常</param>
|
|
public void MarkAsFailed(Exception exception)
|
|
{
|
|
EnterPhase(ArchitecturePhase.FailedInitialization);
|
|
_readyTcs.TrySetException(exception);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 等待架构就绪
|
|
/// </summary>
|
|
public Task WaitUntilReadyAsync() => _readyTcs.Task;
|
|
|
|
#endregion
|
|
}
|