mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-25 13:07:14 +08:00
refactor(architecture): 重构架构阶段验证和初始化流程
- 修改阶段转换验证逻辑,允许从任何阶段转换到 FailedInitialization - 调整初始化流程,确保始终进入各个阶段而不仅仅是有组件时才进入 - 重新排列阶段转换顺序,实现线性状态机模式 - 添加架构阶段线性顺序定义数组 - 更新测试用例以验证初始化失败时抛出异常的情况
This commit is contained in:
parent
177de6d3e6
commit
f70254716b
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user