mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-07 00:39:00 +08:00
- 更新 active tracking / trace 为当前恢复入口,并归档 RP-023 到 RP-025 的阶段细节 - 修复 zh-CN context 页面标题本地化与 troubleshooting 绝对链接后缀不一致问题 - 补充 PR #282 follow-up 的验证记录并确认 docs 站点构建通过
4.3 KiB
4.3 KiB
title, description
| title | description |
|---|---|
| 上下文(Context) | 说明 IArchitectureContext 与 ArchitectureContext 的统一上下文入口和当前推荐用法。 |
上下文(Context)
IArchitectureContext 是框架的统一上下文入口。
当前版本的上下文不再以“公开属性总线”作为主要模型,而是以一组明确的方法同时承载:
- 组件获取
- 事件系统
- 旧 Command / Query 兼容入口
- 新 CQRS runtime 入口
默认实现类型是 ArchitectureContext。
先记住一个事实
如果你还在找旧文档里的这些属性:
CommandBusQueryBusEventBusContainer
那说明你看到的是旧写法。当前推荐入口是方法,不是这些属性式总线。
组件访问
IArchitectureContext 直接提供按类型获取组件的方法:
var context = architecture.Context;
var model = context.GetModel<PlayerModel>();
var system = context.GetSystem<CombatSystem>();
var utility = context.GetUtility<SaveUtility>();
var service = context.GetService<IMyService>();
也支持批量获取和按优先级获取:
GetModels<T>()GetSystems<T>()GetUtilities<T>()GetServices<T>()GetModelsByPriority<T>()GetSystemsByPriority<T>()GetUtilitiesByPriority<T>()GetServicesByPriority<T>()
在 IContextAware 对象里怎么用
大多数业务代码不会手动把 architecture.Context 传来传去,而是通过 IContextAware 扩展方法访问上下文:
using GFramework.Core.Extensions;
public sealed class DamagePlayerCommand : AbstractCommand
{
protected override void OnExecute()
{
var playerModel = this.GetModel<PlayerModel>();
playerModel.Health.Value -= 10;
}
}
常用扩展包括:
GetModel<T>()GetSystem<T>()GetUtility<T>()GetService<T>()SendEvent(...)RegisterEvent(...)SendCommand(...)SendQuery(...)
事件入口
框架事件系统仍然由上下文统一暴露:
context.SendEvent(new PlayerDiedEvent());
var unRegister = context.RegisterEvent<PlayerDiedEvent>(static e =>
{
Console.WriteLine("Player died.");
});
在 IContextAware 对象里也可以直接用扩展:
this.SendEvent(new PlayerDiedEvent());
旧 Command / Query 兼容入口
当前上下文仍保留旧命令 / 查询体系:
SendCommand(ICommand)SendCommand<TResult>(ICommand<TResult>)SendCommandAsync(IAsyncCommand)SendCommandAsync<TResult>(IAsyncCommand<TResult>)SendQuery<TResult>(IQuery<TResult>)SendQueryAsync<TResult>(IAsyncQuery<TResult>)
这部分入口主要用于兼容存量代码。新功能优先看 cqrs。
新 CQRS 入口
IArchitectureContext 也是当前 CQRS runtime 的主入口。最重要的方法是:
SendRequestAsync(...)SendRequest(...)SendAsync(...)PublishAsync(...)CreateStream(...)SendCommandAsync(...)/SendQueryAsync(...)的 CQRS 重载
示例:
var playerId = await architecture.Context.SendRequestAsync(
new CreatePlayerCommand(new CreatePlayerInput("Alice")));
如果你在 IContextAware 对象内部,通常直接用 GFramework.Cqrs.Extensions 里的扩展:
using GFramework.Cqrs.Extensions;
var playerId = await this.SendAsync(
new CreatePlayerCommand(new CreatePlayerInput("Alice")));
GameContext 现在是什么角色
GameContext 仍然存在,但已经退到兼容和回退路径。
ContextAwareBase 在实例未显式注入上下文时,会回退到 GameContext.GetFirstArchitectureContext()。这能保证部分旧代码继续工作,但它不是新代码的首选接法。
新代码更推荐:
- 让对象通过框架流程注入
IArchitectureContext - 或使用
[ContextAware]生成路径 - 或显式从
architecture.Context启动调用链
什么时候需要手动拿 architecture.Context
以下场景适合直接使用 architecture.Context:
- 组合根或启动代码
- 非
IContextAware对象 - 测试中显式驱动请求和事件
- 你要清楚地区分“旧 Command / Query 兼容入口”和“新 CQRS 入口”
继续阅读
- 架构入口:architecture
- 生命周期:lifecycle
- 旧命令系统:command
- 旧查询系统:query
- 新 CQRS runtime:cqrs