---
title: 生命周期管理
description: 当前版本的架构生命周期由阶段模型、初始化顺序、逆序销毁和生命周期钩子共同组成。
---

# 生命周期管理

`GFramework.Core` 的生命周期由 `Architecture` 统一编排，而不是让每个组件各自决定初始化时机。

你真正需要关注的是：

- 阶段枚举 `ArchitecturePhase`
- 组件初始化顺序
- 逆序销毁语义
- `IArchitectureLifecycleHook`

## 阶段模型

当前公开阶段如下：

| 阶段 | 含义 |
| --- | --- |
| `None` | 尚未开始初始化 |
| `BeforeUtilityInit` | 即将初始化工具 |
| `AfterUtilityInit` | 工具初始化完成 |
| `BeforeModelInit` | 即将初始化模型 |
| `AfterModelInit` | 模型初始化完成 |
| `BeforeSystemInit` | 即将初始化系统 |
| `AfterSystemInit` | 系统初始化完成 |
| `Ready` | 架构已完成初始化并可供稳定使用 |
| `Destroying` | 正在销毁 |
| `Destroyed` | 已销毁 |
| `FailedInitialization` | 初始化流程失败 |

正常路径：

```text
None
-> BeforeUtilityInit
-> AfterUtilityInit
-> BeforeModelInit
-> AfterModelInit
-> BeforeSystemInit
-> AfterSystemInit
-> Ready
-> Destroying
-> Destroyed
```

## 初始化顺序

注册顺序和初始化顺序不是一回事。当前框架会按组件类别统一推进：

1. `Utility`
2. `Model`
3. `System`

这保证了大多数系统在初始化时，可以安全依赖已经就绪的工具与模型。

启动方式：

```csharp
var architecture = new GameArchitecture();
await architecture.InitializeAsync();
await architecture.WaitUntilReadyAsync();
```

注册逻辑仍然写在 `OnInitialize()`：

```csharp
protected override void OnInitialize()
{
    RegisterUtility(new SaveUtility());
    RegisterModel(new PlayerModel());
    RegisterSystem(new CombatSystem());
}
```

## 销毁语义

销毁由 `DestroyAsync()` 统一触发，框架会按逆序回收组件。

如果组件实现了异步销毁接口，框架会优先走异步路径。也就是说，新代码应优先实现：

- `IAsyncDestroyable`
- 或其他已有的异步销毁基类路径

同步 `Destroy()` 主要是兼容入口。

## 组件自己的生命周期

大多数组件不需要手写 `Initialize()`；继承框架基类即可。

这里的 `OnInit()` 是组件级入口，用来初始化单个 `Model` / `System`；上面的 `OnInitialize()` 则用于架构级注册：

```csharp
public sealed class PlayerModel : AbstractModel
{
    protected override void OnInit()
    {
    }
}
```

```csharp
public sealed class CombatSystem : AbstractSystem
{
    protected override void OnInit()
    {
    }
}
```

如果你的组件需要真正的异步初始化或销毁，再补对应接口。

## 生命周期钩子

当你需要做横切阶段逻辑时，优先实现 `IArchitectureLifecycleHook`，而不是把这些逻辑分散到某个具体 `System` 里。

```csharp
public sealed class MetricsHook : IArchitectureLifecycleHook
{
    public void OnPhase(ArchitecturePhase phase, IArchitecture architecture)
    {
        if (phase == ArchitecturePhase.Ready)
        {
            Console.WriteLine("Architecture ready.");
        }
    }
}
```

注册方式：

```csharp
architecture.RegisterLifecycleHook(new MetricsHook());
```

## 阶段监听

如果你只需要观察阶段变化，也可以直接订阅：

如果你从旧版本的 `PhaseChanged` 迁移过来，需要把旧写法 `phase => ...` 改成 `(_, args) => ...`，
并通过 `ArchitecturePhaseChangedEventArgs.Phase` 读取阶段值。

```csharp
architecture.PhaseChanged += (_, args) =>
{
    Console.WriteLine($"Phase changed: {args.Phase}");
};
```

## 什么时候会进入 `FailedInitialization`

如果初始化流程中抛出异常，架构会切到 `FailedInitialization`。这意味着：

- `Ready` 不会被触发
- 后续诊断应先回到启动路径
- 文档示例不应假设“只要 new 了 Architecture 就一定能跑到 Ready”

## 推荐做法

- 新代码优先使用 `InitializeAsync()` / `DestroyAsync()`
- 把架构级注册逻辑放在 `OnInitialize()`；组件自己的初始化仍然使用 `OnInit()`，不要再尝试重写 `Init()` 这类旧入口
- 让 `Utility` 承载底层能力，让 `Model` 承载状态，再让 `System` 消费两者
- 跨组件阶段逻辑优先写成 `IArchitectureLifecycleHook`

## 继续阅读

- 架构入口：[architecture](./architecture.md)
- 上下文入口：[context](./context.md)
