# P0-3: Feature 需求详细文档 ## 对齐说明 本文档以 `docs/requirements/p0-requirements-set.md` 为准。Feature 不再自己创建根 scope;GameFlow 创建 FeatureContext 并传入 Feature。Feature 负责自身业务行为和引用清理。 ## 目标 定义业务 Feature 的统一生命周期,让每个玩法、页面流或业务入口可以独立加载、进入、退出和释放。 ## FeatureContext ```csharp public sealed class FeatureContext { public Container Scope { get; } public IResourceGroup Resources { get; } public CompositeDisposable Disposables { get; } public CancellationToken CancellationToken { get; } } ``` 所有权: - `Scope` 由 GameFlow 创建和释放。 - `Resources` 由 GameFlow 创建和释放。 - `Disposables` 由 GameFlow 创建,Feature 可加入订阅,Exit/Dispose 时清理。 - Feature 可以在 `Scope` 内注册自己的临时服务。 ## 生命周期接口 ```csharp public interface IFeature : IDisposable { Task LoadAsync(FeatureContext context); Task EnterAsync(FeatureContext context); Task ExitAsync(FeatureContext context); } ``` 阶段职责: | 方法 | 职责 | |------|------| | `LoadAsync` | 加载资源、创建 ViewModel、准备运行时依赖 | | `EnterAsync` | 打开 UI、订阅 Data 或事件流 | | `ExitAsync` | 关闭 UI、取消业务订阅 | | `Dispose` | 清空自身引用,释放 Feature 自己创建但未交给 context 管理的对象 | ## 数据传递 规则: - 跨 Feature 持久状态放在 Data 类中,并注册到全局 Container。 - 一次性过渡参数由目标 Feature 定义。 - Feature 不引用其他 Feature 的内部类。 - Feature 间直接通信不进入 P0,使用 Data 或 R3 事件流。 ## 资源与订阅 规则: - Feature 加载资源后必须加入 `context.Resources`,或持有明确的 handle 并在 Dispose 中释放。 - Feature 订阅必须加入 `context.Disposables` 或 ViewModel 自己的 `CompositeDisposable`。 - `ExitAsync` 负责停止业务订阅和关闭 UI。 - `Dispose` 必须可重复调用。 ## FeatureBase 可选基类 ```csharp public abstract class FeatureBase : IFeature { protected FeatureContext Context { get; private set; } public virtual Task LoadAsync(FeatureContext context) { Context = context; return Task.CompletedTask; } public virtual Task EnterAsync(FeatureContext context) { return Task.CompletedTask; } public virtual Task ExitAsync(FeatureContext context) { context.Disposables.Clear(); return Task.CompletedTask; } public virtual void Dispose() { Context = null; } } ``` ## 暂不做 - Feature 栈。 - 并行 Feature。 - Feature 热重载。 - Feature 预加载。 - Feature 过渡动画。 - Feature 间直接调用。 ## 验收标准 | # | 标准 | 通过条件 | |---|------|---------| | 1 | Load/Enter/Exit/Dispose 顺序 | GameFlow 严格按顺序调用 | | 2 | 使用 FeatureContext | Feature 可从 context Resolve 服务、加入资源和订阅 | | 3 | 资源释放 | Feature 退出后 context.Resources 已释放 | | 4 | 订阅释放 | Feature 退出后订阅不再触发 | | 5 | Dispose 幂等 | 重复 Dispose 不抛异常 | | 6 | Load 失败清理 | LoadAsync 中途失败后 Dispose 可清理部分状态 | | 7 | Feature 隔离 | Feature 不引用其他 Feature 的内部类 | ## 依赖关系 ```text IFeature ├── FeatureContext ├── Container ├── IResourceGroup └── R3 CompositeDisposable ```