refactor(architecture): 重构架构阶段验证和初始化流程

- 修改阶段转换验证逻辑,允许从任何阶段转换到 FailedInitialization
- 调整初始化流程,确保始终进入各个阶段而不仅仅是有组件时才进入
- 重新排列阶段转换顺序,实现线性状态机模式
- 添加架构阶段线性顺序定义数组
- 更新测试用例以验证初始化失败时抛出异常的情况
This commit is contained in:
GeWuYou 2026-01-17 10:05:52 +08:00
parent 177de6d3e6
commit f70254716b
4 changed files with 92 additions and 53 deletions

View File

@ -1,4 +1,4 @@
using GFramework.Core.Abstractions.enums; using GFramework.Core.Abstractions.enums;
using GFramework.Core.Tests.architecture; using GFramework.Core.Tests.architecture;
using GFramework.Core.Tests.model; using GFramework.Core.Tests.model;
using GFramework.Core.Tests.system; using GFramework.Core.Tests.system;
@ -94,7 +94,7 @@ public class AsyncArchitectureTests : ArchitectureTestsBase<AsyncTestArchitectur
{ {
Architecture!.AddPostRegistrationHook(a => { a.RegisterModel(new FailingModel()); }); Architecture!.AddPostRegistrationHook(a => { a.RegisterModel(new FailingModel()); });
await Architecture.InitializeAsync(); Assert.ThrowsAsync<InvalidOperationException>(async () => await Architecture.InitializeAsync());
Assert.That( Assert.That(
Architecture.CurrentPhase, Architecture.CurrentPhase,
@ -141,7 +141,7 @@ public class AsyncArchitectureTests : ArchitectureTestsBase<AsyncTestArchitectur
a.RegisterModel(new FailingModel()) a.RegisterModel(new FailingModel())
); );
await Architecture.InitializeAsync(); Assert.ThrowsAsync<InvalidOperationException>(async () => await Architecture.InitializeAsync());
AssertInitializationFailed(); AssertInitializationFailed();
} }

View File

@ -1,4 +1,3 @@
using System;
using GFramework.Core.Abstractions.enums; using GFramework.Core.Abstractions.enums;
using GFramework.Core.architecture; using GFramework.Core.architecture;
using GFramework.Core.Tests.architecture; using GFramework.Core.Tests.architecture;
@ -137,7 +136,7 @@ public class SyncArchitectureTests : ArchitectureTestsBase<SyncTestArchitecture>
a.RegisterModel(new FailingModel()) a.RegisterModel(new FailingModel())
); );
Architecture.Initialize(); Assert.Throws<InvalidOperationException>(() => Architecture.Initialize());
AssertInitializationFailed(); AssertInitializationFailed();
} }

View File

@ -134,6 +134,7 @@ public abstract class Architecture(
#region Lifecycle Management #region Lifecycle Management
// ==================== 方案1: 早期返回 (推荐) ====================
/// <summary> /// <summary>
/// 进入指定的架构阶段,并执行相应的生命周期管理操作 /// 进入指定的架构阶段,并执行相应的生命周期管理操作
/// </summary> /// </summary>
@ -141,29 +142,57 @@ public abstract class Architecture(
/// <exception cref="InvalidOperationException">当阶段转换不被允许时抛出异常</exception> /// <exception cref="InvalidOperationException">当阶段转换不被允许时抛出异常</exception>
protected virtual void EnterPhase(ArchitecturePhase next) protected virtual void EnterPhase(ArchitecturePhase next)
{ {
if (Configuration.ArchitectureProperties.StrictPhaseValidation && // 验证阶段转换
(!ArchitectureConstants.PhaseTransitions.TryGetValue(CurrentPhase, out var allowed) || ValidatePhaseTransition(next);
!allowed.Contains(next)))
{
// 验证阶段转换是否合法
var errorMsg = $"Invalid phase transition: {CurrentPhase} -> {next}";
_logger.Fatal(errorMsg);
throw new InvalidOperationException(errorMsg);
}
// 执行阶段转换
var previousPhase = CurrentPhase; var previousPhase = CurrentPhase;
CurrentPhase = next; CurrentPhase = next;
if (previousPhase != next) if (previousPhase != next)
_logger.Info($"Architecture phase changed: {previousPhase} -> {next}"); _logger.Info($"Architecture phase changed: {previousPhase} -> {next}");
// 通知阶段变更
NotifyPhase(next); NotifyPhase(next);
NotifyPhaseAwareObjects(next);
}
// 通知所有架构阶段感知对象阶段变更 /// <summary>
/// 验证阶段转换是否合法
/// </summary>
/// <param name="next">目标阶段</param>
/// <exception cref="InvalidOperationException">当阶段转换不合法时抛出</exception>
private void ValidatePhaseTransition(ArchitecturePhase next)
{
// 不需要严格验证,直接返回
if (!Configuration.ArchitectureProperties.StrictPhaseValidation)
return;
// FailedInitialization 可以从任何阶段转换,直接返回
if (next == ArchitecturePhase.FailedInitialization)
return;
// 检查转换是否在允许列表中
if (ArchitectureConstants.PhaseTransitions.TryGetValue(CurrentPhase, out var allowed) &&
allowed.Contains(next))
return;
// 转换不合法,抛出异常
var errorMsg = $"Invalid phase transition: {CurrentPhase} -> {next}";
_logger.Fatal(errorMsg);
throw new InvalidOperationException(errorMsg);
}
/// <summary>
/// 通知所有架构阶段感知对象阶段变更
/// </summary>
/// <param name="phase">新阶段</param>
private void NotifyPhaseAwareObjects(ArchitecturePhase phase)
{
foreach (var obj in Container.GetAll<IArchitecturePhaseAware>()) foreach (var obj in Container.GetAll<IArchitecturePhaseAware>())
{ {
_logger.Trace($"Notifying phase-aware object {obj.GetType().Name} of phase change to {next}"); _logger.Trace($"Notifying phase-aware object {obj.GetType().Name} of phase change to {phase}");
obj.OnArchitecturePhase(next); obj.OnArchitecturePhase(phase);
} }
} }
@ -232,10 +261,11 @@ public abstract class Architecture(
var models = _pendingInitializableList.OfType<IModel>().ToList(); var models = _pendingInitializableList.OfType<IModel>().ToList();
var systems = _pendingInitializableList.OfType<ISystem>().ToList(); var systems = _pendingInitializableList.OfType<ISystem>().ToList();
// 1. 初始化工具 // 1. 工具初始化阶段(始终进入阶段,仅在有组件时执行初始化)
EnterPhase(ArchitecturePhase.BeforeUtilityInit);
if (utilities.Count != 0) if (utilities.Count != 0)
{ {
EnterPhase(ArchitecturePhase.BeforeUtilityInit);
_logger.Info($"Initializing {utilities.Count} context utilities"); _logger.Info($"Initializing {utilities.Count} context utilities");
foreach (var utility in utilities) foreach (var utility in utilities)
@ -244,14 +274,16 @@ public abstract class Architecture(
await InitializeComponentAsync(utility, asyncMode); await InitializeComponentAsync(utility, asyncMode);
} }
EnterPhase(ArchitecturePhase.AfterUtilityInit);
_logger.Info("All context utilities initialized"); _logger.Info("All context utilities initialized");
} }
// 2. 初始化模型 EnterPhase(ArchitecturePhase.AfterUtilityInit);
// 2. 模型初始化阶段(始终进入阶段,仅在有组件时执行初始化)
EnterPhase(ArchitecturePhase.BeforeModelInit);
if (models.Count != 0) if (models.Count != 0)
{ {
EnterPhase(ArchitecturePhase.BeforeModelInit);
_logger.Info($"Initializing {models.Count} models"); _logger.Info($"Initializing {models.Count} models");
foreach (var model in models) foreach (var model in models)
@ -260,14 +292,16 @@ public abstract class Architecture(
await InitializeComponentAsync(model, asyncMode); await InitializeComponentAsync(model, asyncMode);
} }
EnterPhase(ArchitecturePhase.AfterModelInit);
_logger.Info("All models initialized"); _logger.Info("All models initialized");
} }
// 3. 初始化系统 EnterPhase(ArchitecturePhase.AfterModelInit);
// 3. 系统初始化阶段(始终进入阶段,仅在有组件时执行初始化)
EnterPhase(ArchitecturePhase.BeforeSystemInit);
if (systems.Count != 0) if (systems.Count != 0)
{ {
EnterPhase(ArchitecturePhase.BeforeSystemInit);
_logger.Info($"Initializing {systems.Count} systems"); _logger.Info($"Initializing {systems.Count} systems");
foreach (var system in systems) foreach (var system in systems)
@ -276,10 +310,11 @@ public abstract class Architecture(
await InitializeComponentAsync(system, asyncMode); await InitializeComponentAsync(system, asyncMode);
} }
EnterPhase(ArchitecturePhase.AfterSystemInit);
_logger.Info("All systems initialized"); _logger.Info("All systems initialized");
} }
EnterPhase(ArchitecturePhase.AfterSystemInit);
_pendingInitializableList.Clear(); _pendingInitializableList.Clear();
_logger.Info("All components initialized"); _logger.Info("All components initialized");
} }

View File

@ -1,4 +1,4 @@
using System.Collections.Immutable; using System.Collections.Immutable;
using GFramework.Core.Abstractions.enums; using GFramework.Core.Abstractions.enums;
namespace GFramework.Core.architecture; namespace GFramework.Core.architecture;
@ -8,42 +8,47 @@ namespace GFramework.Core.architecture;
/// </summary> /// </summary>
public static class ArchitectureConstants public static class ArchitectureConstants
{ {
/// <summary>
/// 定义架构阶段的线性顺序
/// </summary>
/// <remarks>
/// 架构阶段永远按照此顺序线性进行,无论是否有组件注册
/// </remarks>
public static readonly ArchitecturePhase[] PhaseOrder =
[
ArchitecturePhase.None,
ArchitecturePhase.BeforeUtilityInit,
ArchitecturePhase.AfterUtilityInit,
ArchitecturePhase.BeforeModelInit,
ArchitecturePhase.AfterModelInit,
ArchitecturePhase.BeforeSystemInit,
ArchitecturePhase.AfterSystemInit,
ArchitecturePhase.Ready,
ArchitecturePhase.Destroying,
ArchitecturePhase.Destroyed
];
/// <summary> /// <summary>
/// 定义架构阶段之间的有效转换关系 /// 定义架构阶段之间的有效转换关系
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// 键为当前架构阶段,值为从该阶段可以转换到的下一阶段数组 /// 键为当前架构阶段,值为从该阶段可以转换到的下一阶段数组
/// 架构采用线性状态机模式,只允许顺序转换,但允许从任何阶段转到 FailedInitialization
/// </remarks> /// </remarks>
public static readonly ImmutableDictionary<ArchitecturePhase, ArchitecturePhase[]> PhaseTransitions = public static readonly ImmutableDictionary<ArchitecturePhase, ArchitecturePhase[]> PhaseTransitions =
new Dictionary<ArchitecturePhase, ArchitecturePhase[]> new Dictionary<ArchitecturePhase, ArchitecturePhase[]>
{ {
// 正常线性流程
{ ArchitecturePhase.None, [ArchitecturePhase.BeforeUtilityInit] }, { ArchitecturePhase.None, [ArchitecturePhase.BeforeUtilityInit] },
{ { ArchitecturePhase.BeforeUtilityInit, [ArchitecturePhase.AfterUtilityInit] },
ArchitecturePhase.BeforeUtilityInit, { ArchitecturePhase.AfterUtilityInit, [ArchitecturePhase.BeforeModelInit] },
[ArchitecturePhase.AfterUtilityInit, ArchitecturePhase.FailedInitialization] { ArchitecturePhase.BeforeModelInit, [ArchitecturePhase.AfterModelInit] },
}, { ArchitecturePhase.AfterModelInit, [ArchitecturePhase.BeforeSystemInit] },
{ { ArchitecturePhase.BeforeSystemInit, [ArchitecturePhase.AfterSystemInit] },
ArchitecturePhase.AfterUtilityInit, { ArchitecturePhase.AfterSystemInit, [ArchitecturePhase.Ready] },
[ArchitecturePhase.BeforeModelInit, ArchitecturePhase.FailedInitialization]
},
{
ArchitecturePhase.BeforeModelInit, [
ArchitecturePhase.AfterModelInit, ArchitecturePhase.FailedInitialization
]
},
{
ArchitecturePhase.AfterModelInit, [
ArchitecturePhase.BeforeSystemInit, ArchitecturePhase.FailedInitialization
]
},
{
ArchitecturePhase.BeforeSystemInit, [
ArchitecturePhase.AfterSystemInit, ArchitecturePhase.FailedInitialization
]
},
{ ArchitecturePhase.AfterSystemInit, [ArchitecturePhase.Ready, ArchitecturePhase.FailedInitialization] },
{ ArchitecturePhase.Ready, [ArchitecturePhase.Destroying] }, { ArchitecturePhase.Ready, [ArchitecturePhase.Destroying] },
{ ArchitecturePhase.FailedInitialization, [ArchitecturePhase.Destroying] }, { ArchitecturePhase.Destroying, [ArchitecturePhase.Destroyed] },
{ ArchitecturePhase.Destroying, [ArchitecturePhase.Destroyed] } // 失败路径:从任何阶段都可以转到 FailedInitialization
{ ArchitecturePhase.FailedInitialization, [ArchitecturePhase.Destroying] }
}.ToImmutableDictionary(); }.ToImmutableDictionary();
} }