mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 19:03:29 +08:00
Compare commits
No commits in common. "main" and "v0.0.20" have entirely different histories.
@ -1,62 +0,0 @@
|
||||
schema_version: 1
|
||||
generated_at_utc: "2026-03-21T04:47:58Z"
|
||||
generated_from: ".ai/environment/tools.raw.yaml"
|
||||
generator: "scripts/generate-ai-environment.py"
|
||||
platform:
|
||||
family: "wsl-linux"
|
||||
os: "Linux"
|
||||
distro: "Ubuntu 24.04.4 LTS"
|
||||
shell: "bash"
|
||||
capabilities:
|
||||
dotnet: true
|
||||
python: true
|
||||
node: true
|
||||
bun: true
|
||||
docker: true
|
||||
fast_search: true
|
||||
json_cli: true
|
||||
tool_selection:
|
||||
search:
|
||||
preferred: "rg"
|
||||
fallback: "grep"
|
||||
use_for: "Repository text search."
|
||||
json:
|
||||
preferred: "jq"
|
||||
fallback: "python3"
|
||||
use_for: "Inspecting or transforming JSON command output."
|
||||
shell:
|
||||
preferred: "bash"
|
||||
fallback: "sh"
|
||||
use_for: "Repository shell scripts and command execution."
|
||||
scripting:
|
||||
preferred: "python3"
|
||||
fallback: "bash"
|
||||
use_for: "Non-trivial local automation and helper scripts."
|
||||
docs_package_manager:
|
||||
preferred: "bun"
|
||||
fallback: "npm"
|
||||
use_for: "Installing and previewing the docs site."
|
||||
build_and_test:
|
||||
preferred: "dotnet"
|
||||
fallback: "unavailable"
|
||||
use_for: "Build, test, restore, and solution validation."
|
||||
python:
|
||||
available: true
|
||||
helper_packages:
|
||||
requests: true
|
||||
rich: true
|
||||
openai: false
|
||||
tiktoken: false
|
||||
pydantic: false
|
||||
pytest: false
|
||||
preferences:
|
||||
prefer_project_listed_tools: true
|
||||
prefer_python_for_non_trivial_automation: true
|
||||
avoid_unlisted_system_tools: true
|
||||
rules:
|
||||
- "Use rg instead of grep for repository search when rg is available."
|
||||
- "Use jq for JSON inspection; fall back to python3 if jq is unavailable."
|
||||
- "Prefer python3 over complex bash for non-trivial scripting when python3 is available."
|
||||
- "Use bun for docs preview workflows when bun is available; otherwise fall back to npm."
|
||||
- "Use dotnet for repository build and test workflows."
|
||||
- "Do not assume unrelated system tools are part of the supported project environment."
|
||||
@ -1,89 +0,0 @@
|
||||
schema_version: 1
|
||||
generated_at_utc: "2026-03-21T04:47:28Z"
|
||||
generator: "scripts/collect-dev-environment.sh"
|
||||
|
||||
platform:
|
||||
os: "Linux"
|
||||
distro: "Ubuntu 24.04.4 LTS"
|
||||
version: "24.04"
|
||||
kernel: "5.15.167.4-microsoft-standard-WSL2"
|
||||
wsl: true
|
||||
wsl_version: "2.4.13"
|
||||
shell: "bash"
|
||||
|
||||
required_runtimes:
|
||||
dotnet:
|
||||
installed: true
|
||||
version: "10.0.104"
|
||||
path: "/usr/bin/dotnet"
|
||||
purpose: "Builds and tests the GFramework solution."
|
||||
python3:
|
||||
installed: true
|
||||
version: "Python 3.12.3"
|
||||
path: "/usr/bin/python3"
|
||||
purpose: "Runs local automation and environment collection scripts."
|
||||
node:
|
||||
installed: true
|
||||
version: "v20.20.1"
|
||||
path: "/usr/bin/node"
|
||||
purpose: "Provides the JavaScript runtime used by docs tooling."
|
||||
bun:
|
||||
installed: true
|
||||
version: "1.3.10"
|
||||
path: "/root/.bun/bin/bun"
|
||||
purpose: "Installs and previews the VitePress documentation site."
|
||||
|
||||
required_tools:
|
||||
git:
|
||||
installed: true
|
||||
version: "git version 2.43.0"
|
||||
path: "/usr/bin/git"
|
||||
purpose: "Source control and patch review."
|
||||
bash:
|
||||
installed: true
|
||||
version: "GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)"
|
||||
path: "/usr/bin/bash"
|
||||
purpose: "Executes repository scripts and shell automation."
|
||||
rg:
|
||||
installed: true
|
||||
version: "ripgrep 15.1.0 (rev af60c2de9d)"
|
||||
path: "/root/.bun/install/global/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/path/rg"
|
||||
purpose: "Fast text search across the repository."
|
||||
jq:
|
||||
installed: true
|
||||
version: "jq-1.7"
|
||||
path: "/usr/bin/jq"
|
||||
purpose: "Inspecting and transforming JSON outputs."
|
||||
|
||||
project_tools:
|
||||
docker:
|
||||
installed: true
|
||||
version: "Docker version 29.2.1, build a5c7197"
|
||||
path: "/usr/bin/docker"
|
||||
purpose: "Runs MegaLinter and other containerized validation tools."
|
||||
|
||||
python_packages:
|
||||
requests:
|
||||
installed: true
|
||||
version: "2.31.0"
|
||||
purpose: "Simple HTTP calls in local helper scripts."
|
||||
rich:
|
||||
installed: true
|
||||
version: "13.7.1"
|
||||
purpose: "Readable CLI output for local Python helpers."
|
||||
openai:
|
||||
installed: false
|
||||
version: "not-installed"
|
||||
purpose: "Optional scripted access to OpenAI APIs."
|
||||
tiktoken:
|
||||
installed: false
|
||||
version: "not-installed"
|
||||
purpose: "Optional token counting for prompt and context inspection."
|
||||
pydantic:
|
||||
installed: false
|
||||
version: "not-installed"
|
||||
purpose: "Optional typed config and schema validation for helper scripts."
|
||||
pytest:
|
||||
installed: false
|
||||
version: "not-installed"
|
||||
purpose: "Optional lightweight testing for Python helper scripts."
|
||||
@ -1,469 +0,0 @@
|
||||
# VitePress 文档生成 Skills 系统
|
||||
|
||||
为 GFramework 项目提供自动化的 VitePress 文档生成能力。
|
||||
|
||||
## 概述
|
||||
|
||||
这是一套专门为 GFramework 项目设计的文档生成 skills,能够根据 C# 源代码自动生成高质量的 VitePress 文档。系统采用模块化设计,每个 skill 专注于特定的文档生成任务。
|
||||
|
||||
## 可用 Skills
|
||||
|
||||
### 1. vitepress-api-doc - API 文档生成
|
||||
|
||||
为单个 C# 文件生成 API 参考文档。
|
||||
|
||||
**用途**:
|
||||
- 类、接口、枚举的 API 文档
|
||||
- 方法、属性、事件的详细说明
|
||||
- 基于 XML 注释生成文档
|
||||
|
||||
**调用方式**:
|
||||
```bash
|
||||
/vitepress-api-doc <C# 文件路径>
|
||||
```
|
||||
|
||||
**示例**:
|
||||
```bash
|
||||
/vitepress-api-doc GFramework.Core/architecture/Architecture.cs
|
||||
```
|
||||
|
||||
**输出位置**:`docs/zh-CN/api-reference/<模块>/<文件名>.md`
|
||||
|
||||
[详细文档](./vitepress-api-doc/SKILL.md)
|
||||
|
||||
---
|
||||
|
||||
### 2. vitepress-guide - 功能指南生成
|
||||
|
||||
生成功能模块的使用指南文档。
|
||||
|
||||
**用途**:
|
||||
- 核心功能模块的使用说明
|
||||
- 设计模式和架构概念
|
||||
- 最佳实践和常见问题
|
||||
|
||||
**调用方式**:
|
||||
```bash
|
||||
/vitepress-guide <主题> <目标模块>
|
||||
```
|
||||
|
||||
**示例**:
|
||||
```bash
|
||||
/vitepress-guide "事件系统" Core
|
||||
/vitepress-guide "IoC 容器" Core
|
||||
```
|
||||
|
||||
**输出位置**:`docs/zh-CN/<模块>/<主题>.md`
|
||||
|
||||
[详细文档](./vitepress-guide/SKILL.md)
|
||||
|
||||
---
|
||||
|
||||
### 3. vitepress-tutorial - 分步教程生成
|
||||
|
||||
生成分步教程文档,适合初学者学习。
|
||||
|
||||
**用途**:
|
||||
- 框架入门教程
|
||||
- 功能实现教程
|
||||
- 问题解决方案
|
||||
|
||||
**调用方式**:
|
||||
```bash
|
||||
/vitepress-tutorial <教程主题>
|
||||
```
|
||||
|
||||
**示例**:
|
||||
```bash
|
||||
/vitepress-tutorial "创建第一个 System"
|
||||
/vitepress-tutorial "使用事件系统"
|
||||
```
|
||||
|
||||
**输出位置**:`docs/zh-CN/tutorials/<主题>.md`
|
||||
|
||||
[详细文档](./vitepress-tutorial/SKILL.md)
|
||||
|
||||
---
|
||||
|
||||
### 4. vitepress-batch-api - 批量 API 文档生成
|
||||
|
||||
为整个模块批量生成 API 文档。
|
||||
|
||||
**用途**:
|
||||
- 初始化模块文档
|
||||
- 更新整个模块的文档
|
||||
- 快速生成大量文档
|
||||
|
||||
**调用方式**:
|
||||
```bash
|
||||
/vitepress-batch-api <模块名>
|
||||
```
|
||||
|
||||
**示例**:
|
||||
```bash
|
||||
/vitepress-batch-api Core
|
||||
/vitepress-batch-api Godot
|
||||
```
|
||||
|
||||
**输出位置**:`docs/zh-CN/api-reference/<模块>/`
|
||||
|
||||
[详细文档](./vitepress-batch-api/SKILL.md)
|
||||
|
||||
---
|
||||
|
||||
### 5. vitepress-validate - 文档验证
|
||||
|
||||
验证文档的质量和规范性。
|
||||
|
||||
**用途**:
|
||||
- Frontmatter 格式验证
|
||||
- 内部链接有效性检查
|
||||
- 代码块语法验证
|
||||
- 标点符号规范检查
|
||||
|
||||
**调用方式**:
|
||||
```bash
|
||||
/vitepress-validate <文件或目录路径>
|
||||
```
|
||||
|
||||
**示例**:
|
||||
```bash
|
||||
/vitepress-validate docs/zh-CN/api-reference/core/architecture.md
|
||||
/vitepress-validate docs/zh-CN/
|
||||
```
|
||||
|
||||
[详细文档](./vitepress-validate/SKILL.md)
|
||||
|
||||
---
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 生成单个 API 文档
|
||||
|
||||
```bash
|
||||
# 为 Architecture 类生成文档
|
||||
/vitepress-api-doc GFramework.Core/architecture/Architecture.cs
|
||||
```
|
||||
|
||||
### 2. 批量生成模块文档
|
||||
|
||||
```bash
|
||||
# 为整个 Core 模块生成文档
|
||||
/vitepress-batch-api Core
|
||||
```
|
||||
|
||||
### 3. 生成功能指南
|
||||
|
||||
```bash
|
||||
# 生成事件系统使用指南
|
||||
/vitepress-guide "事件系统" Core
|
||||
```
|
||||
|
||||
### 4. 生成教程
|
||||
|
||||
```bash
|
||||
# 生成创建 Model 的教程
|
||||
/vitepress-tutorial "创建第一个 Model"
|
||||
```
|
||||
|
||||
### 5. 验证文档
|
||||
|
||||
```bash
|
||||
# 验证生成的文档
|
||||
/vitepress-validate docs/zh-CN/api-reference/core/
|
||||
```
|
||||
|
||||
## 工作流程
|
||||
|
||||
### 典型工作流程
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[开始] --> B{文档类型?}
|
||||
B -->|API 文档| C[/vitepress-api-doc]
|
||||
B -->|功能指南| D[/vitepress-guide]
|
||||
B -->|教程| E[/vitepress-tutorial]
|
||||
C --> F[/vitepress-validate]
|
||||
D --> F
|
||||
E --> F
|
||||
F --> G{验证通过?}
|
||||
G -->|是| H[完成]
|
||||
G -->|否| I[修复问题]
|
||||
I --> F
|
||||
```
|
||||
|
||||
### 推荐流程
|
||||
|
||||
1. **初始化模块文档**
|
||||
```bash
|
||||
/vitepress-batch-api Core
|
||||
```
|
||||
|
||||
2. **生成功能指南**
|
||||
```bash
|
||||
/vitepress-guide "IoC 容器" Core
|
||||
/vitepress-guide "事件系统" Core
|
||||
```
|
||||
|
||||
3. **生成教程**
|
||||
```bash
|
||||
/vitepress-tutorial "创建第一个 Model"
|
||||
/vitepress-tutorial "使用命令系统"
|
||||
```
|
||||
|
||||
4. **验证所有文档**
|
||||
```bash
|
||||
/vitepress-validate docs/zh-CN/
|
||||
```
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
.claude/skills/
|
||||
├── README.md # 本文件
|
||||
├── _shared/ # 共享资源
|
||||
│ └── scripts/ # 共享脚本
|
||||
│ ├── update-vitepress-nav.sh # 更新导航配置
|
||||
│ ├── parse-csharp-xml.sh # 解析 XML 注释
|
||||
│ └── generate-examples.sh # 生成代码示例
|
||||
│
|
||||
├── vitepress-api-doc/ # API 文档生成
|
||||
│ ├── SKILL.md # Skill 说明
|
||||
│ ├── template.md # 文档模板
|
||||
│ └── examples/ # 示例文档
|
||||
│ ├── class-example.md
|
||||
│ ├── interface-example.md
|
||||
│ └── enum-example.md
|
||||
│
|
||||
├── vitepress-guide/ # 功能指南生成
|
||||
│ ├── SKILL.md
|
||||
│ ├── template.md
|
||||
│ └── examples/
|
||||
│ └── guide-example.md
|
||||
│
|
||||
├── vitepress-tutorial/ # 教程生成
|
||||
│ ├── SKILL.md
|
||||
│ ├── template.md
|
||||
│ └── examples/
|
||||
│ └── tutorial-example.md
|
||||
│
|
||||
├── vitepress-batch-api/ # 批量 API 文档生成
|
||||
│ ├── SKILL.md
|
||||
│ └── scripts/
|
||||
│ └── batch-generate.sh
|
||||
│
|
||||
└── vitepress-validate/ # 文档验证
|
||||
├── SKILL.md
|
||||
└── scripts/
|
||||
├── validate-frontmatter.sh
|
||||
├── validate-links.sh
|
||||
├── validate-code-blocks.sh
|
||||
└── validate-all.sh
|
||||
```
|
||||
|
||||
## 设计原则
|
||||
|
||||
### 1. 单一职责
|
||||
|
||||
每个 skill 专注于一个特定任务:
|
||||
- `vitepress-api-doc` - 单文件 API 文档
|
||||
- `vitepress-guide` - 功能指南
|
||||
- `vitepress-tutorial` - 分步教程
|
||||
- `vitepress-batch-api` - 批量生成
|
||||
- `vitepress-validate` - 质量验证
|
||||
|
||||
### 2. 模块化设计
|
||||
|
||||
- 共享脚本放在 `_shared/scripts/`
|
||||
- 每个 skill 独立维护
|
||||
- 可以单独使用或组合使用
|
||||
|
||||
### 3. 基于源代码
|
||||
|
||||
- 仅使用 XML 注释,不添加 AI 补充
|
||||
- 保持文档与代码同步
|
||||
- 代码示例由 AI 自动生成
|
||||
|
||||
### 4. 质量保证
|
||||
|
||||
- 所有生成的文档都应通过验证
|
||||
- 遵循 VitePress 规范
|
||||
- 保持一致的文档风格
|
||||
|
||||
## 文档规范
|
||||
|
||||
### Frontmatter 格式
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: 文档标题
|
||||
description: 简短描述(1-2 句话)
|
||||
outline: deep # 可选
|
||||
---
|
||||
```
|
||||
|
||||
### 代码块标记
|
||||
|
||||
- C# 代码使用 `csharp`
|
||||
- Bash 脚本使用 `bash`
|
||||
- JSON 使用 `json`
|
||||
- YAML 使用 `yaml`
|
||||
|
||||
### 泛型符号转义
|
||||
|
||||
在正文中使用 HTML 实体:
|
||||
- `List<T>` → `List<T>`
|
||||
- 代码块内保持原样
|
||||
|
||||
### 中文标点符号
|
||||
|
||||
- 中文句子使用全角标点:,。!?
|
||||
- 英文句子使用半角标点:,.!?
|
||||
- 代码周围使用半角符号
|
||||
|
||||
## 共享脚本
|
||||
|
||||
### update-vitepress-nav.sh
|
||||
|
||||
更新 VitePress 侧边栏导航配置。
|
||||
|
||||
**用法**:
|
||||
```bash
|
||||
.claude/skills/_shared/scripts/update-vitepress-nav.sh <文件路径> <标题>
|
||||
```
|
||||
|
||||
### parse-csharp-xml.sh
|
||||
|
||||
解析 C# XML 文档注释。
|
||||
|
||||
**用法**:
|
||||
```bash
|
||||
.claude/skills/_shared/scripts/parse-csharp-xml.sh <C# 文件路径>
|
||||
```
|
||||
|
||||
### generate-examples.sh
|
||||
|
||||
生成代码示例。
|
||||
|
||||
**用法**:
|
||||
```bash
|
||||
.claude/skills/_shared/scripts/generate-examples.sh <类型名> <命名空间>
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 文档生成顺序
|
||||
|
||||
1. 先生成 API 文档(基础)
|
||||
2. 再生成功能指南(概念)
|
||||
3. 最后生成教程(实践)
|
||||
|
||||
### 2. 保持文档同步
|
||||
|
||||
- 修改代码后及时更新文档
|
||||
- 使用单文件生成更新特定文档
|
||||
- 定期批量验证所有文档
|
||||
|
||||
### 3. 质量控制
|
||||
|
||||
- 生成后立即验证
|
||||
- 修复所有错误和警告
|
||||
- 确保链接有效
|
||||
|
||||
### 4. 版本控制
|
||||
|
||||
- 将生成的文档提交到 Git
|
||||
- 在 PR 中包含文档更新
|
||||
- 保持文档与代码版本一致
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 问题:生成的文档缺少内容
|
||||
|
||||
**原因**:源代码缺少 XML 注释
|
||||
|
||||
**解决方案**:
|
||||
1. 在源代码中添加 XML 注释
|
||||
2. 重新生成文档
|
||||
|
||||
### 问题:验证失败
|
||||
|
||||
**原因**:文档格式不符合规范
|
||||
|
||||
**解决方案**:
|
||||
1. 查看验证错误信息
|
||||
2. 根据提示修复问题
|
||||
3. 重新验证
|
||||
|
||||
### 问题:链接损坏
|
||||
|
||||
**原因**:文件路径错误或文件不存在
|
||||
|
||||
**解决方案**:
|
||||
1. 检查链接的目标文件是否存在
|
||||
2. 修正文件路径
|
||||
3. 重新验证
|
||||
|
||||
### 问题:批量生成速度慢
|
||||
|
||||
**原因**:文件数量多
|
||||
|
||||
**解决方案**:
|
||||
1. 使用 `--parallel` 选项(如果支持)
|
||||
2. 分批生成
|
||||
3. 仅生成修改的文件
|
||||
|
||||
## 扩展开发
|
||||
|
||||
### 添加新 Skill
|
||||
|
||||
1. 在 `.claude/skills/` 下创建新目录
|
||||
2. 创建 `SKILL.md` 说明文档
|
||||
3. 创建必要的模板和脚本
|
||||
4. 在本 README 中添加说明
|
||||
|
||||
### 修改现有 Skill
|
||||
|
||||
1. 更新 `SKILL.md` 文档
|
||||
2. 修改模板或脚本
|
||||
3. 更新示例文档
|
||||
4. 测试修改后的功能
|
||||
|
||||
## 贡献指南
|
||||
|
||||
### 报告问题
|
||||
|
||||
在 GitHub Issues 中报告问题,包含:
|
||||
- 使用的 skill 名称
|
||||
- 输入参数
|
||||
- 预期结果
|
||||
- 实际结果
|
||||
- 错误信息
|
||||
|
||||
### 提交改进
|
||||
|
||||
1. Fork 项目
|
||||
2. 创建功能分支
|
||||
3. 提交修改
|
||||
4. 创建 Pull Request
|
||||
|
||||
## 版本历史
|
||||
|
||||
- v1.0.0 (2025-01-XX) - 初始版本
|
||||
- 5 个核心 skills
|
||||
- 3 个共享脚本
|
||||
- 完整的文档和示例
|
||||
|
||||
## 许可证
|
||||
|
||||
与 GFramework 项目保持一致。
|
||||
|
||||
## 联系方式
|
||||
|
||||
如有问题或建议,请通过以下方式联系:
|
||||
- GitHub Issues
|
||||
- 项目讨论区
|
||||
|
||||
---
|
||||
|
||||
**注意**:本 skills 系统专为 GFramework 项目设计,使用前请确保了解项目结构和文档规范。
|
||||
@ -1,205 +0,0 @@
|
||||
# GFramework 文档编写规范
|
||||
|
||||
## Markdown 语法规范
|
||||
|
||||
### 1. 泛型标记转义
|
||||
|
||||
在 Markdown 文档中,所有泛型标记必须转义,否则会被 VitePress 误认为 HTML 标签。
|
||||
|
||||
**错误示例**:
|
||||
```markdown
|
||||
`Option<T>` 是一个泛型类型
|
||||
`Result<TValue, TError>` 表示结果
|
||||
public class Repository<TData> { }
|
||||
```
|
||||
|
||||
**正确示例**:
|
||||
```markdown
|
||||
`Option<T>` 是一个泛型类型
|
||||
`Result<TValue, TError>` 表示结果
|
||||
public class Repository<TData> { }
|
||||
```
|
||||
|
||||
**常见泛型标记**:
|
||||
- `<T>` → `<T>`
|
||||
- `<TResult>` → `<TResult>`
|
||||
- `<TValue>` → `<TValue>`
|
||||
- `<TError>` → `<TError>`
|
||||
- `<TSaveData>` → `<TSaveData>`
|
||||
- `<TData>` → `<TData>`
|
||||
- `<TNode>` → `<TNode>`
|
||||
|
||||
### 2. HTML 标签转义
|
||||
|
||||
如果需要在文档中显示 HTML 标签,必须转义:
|
||||
- `<summary>` → `<summary>`
|
||||
- `<param>` → `<param>`
|
||||
- `<returns>` → `<returns>`
|
||||
|
||||
### 3. 链接验证
|
||||
|
||||
**内部链接规则**:
|
||||
- 使用相对路径: `/zh-CN/core/events`
|
||||
- 确保目标文件存在
|
||||
- 不要链接到尚未创建的页面
|
||||
|
||||
**已存在的文档路径**:
|
||||
|
||||
**Core 模块**:
|
||||
- `/zh-CN/core/architecture` - 架构系统
|
||||
- `/zh-CN/core/ioc` - IoC 容器
|
||||
- `/zh-CN/core/events` - 事件系统
|
||||
- `/zh-CN/core/command` - 命令系统
|
||||
- `/zh-CN/core/query` - 查询系统
|
||||
- `/zh-CN/core/model` - Model 系统
|
||||
- `/zh-CN/core/system` - System 系统
|
||||
- `/zh-CN/core/utility` - Utility 系统
|
||||
- `/zh-CN/core/controller` - Controller 系统
|
||||
- `/zh-CN/core/logging` - 日志系统
|
||||
- `/zh-CN/core/pool` - 对象池
|
||||
- `/zh-CN/core/property` - 可绑定属性
|
||||
- `/zh-CN/core/lifecycle` - 生命周期管理
|
||||
- `/zh-CN/core/coroutine` - 协程系统
|
||||
- `/zh-CN/core/resource` - 资源管理
|
||||
- `/zh-CN/core/state-machine` - 状态机
|
||||
- `/zh-CN/core/cqrs` - CQRS 与 Mediator
|
||||
- `/zh-CN/core/functional` - 函数式编程
|
||||
- `/zh-CN/core/pause` - 暂停管理
|
||||
- `/zh-CN/core/configuration` - 配置管理
|
||||
- `/zh-CN/core/ecs` - ECS 系统集成
|
||||
- `/zh-CN/core/extensions` - 扩展方法
|
||||
- `/zh-CN/core/rule` - 规则系统
|
||||
- `/zh-CN/core/environment` - 环境系统
|
||||
- `/zh-CN/core/context` - 上下文系统
|
||||
- `/zh-CN/core/async-initialization` - 异步初始化
|
||||
|
||||
**Game 模块**:
|
||||
- `/zh-CN/game/scene` - 场景系统
|
||||
- `/zh-CN/game/ui` - UI 系统
|
||||
- `/zh-CN/game/data` - 数据与存档
|
||||
- `/zh-CN/game/storage` - 存储系统
|
||||
- `/zh-CN/game/serialization` - 序列化系统
|
||||
- `/zh-CN/game/setting` - 设置系统
|
||||
|
||||
**Godot 模块**:
|
||||
- `/zh-CN/godot/architecture` - Godot 架构集成
|
||||
- `/zh-CN/godot/scene` - Godot 场景系统
|
||||
- `/zh-CN/godot/ui` - Godot UI 系统
|
||||
- `/zh-CN/godot/pool` - Godot 节点池
|
||||
- `/zh-CN/godot/resource` - Godot 资源仓储
|
||||
- `/zh-CN/godot/logging` - Godot 日志系统
|
||||
- `/zh-CN/godot/pause` - Godot 暂停处理
|
||||
- `/zh-CN/godot/extensions` - Godot 扩展
|
||||
- `/zh-CN/godot/coroutine` - Godot 协程
|
||||
- `/zh-CN/godot/signal` - Godot 信号
|
||||
- `/zh-CN/godot/storage` - Godot 存储
|
||||
|
||||
**教程**:
|
||||
- `/zh-CN/tutorials/coroutine-tutorial` - 协程系统教程
|
||||
- `/zh-CN/tutorials/state-machine-tutorial` - 状态机教程
|
||||
- `/zh-CN/tutorials/resource-management` - 资源管理教程
|
||||
- `/zh-CN/tutorials/save-system` - 存档系统教程
|
||||
- `/zh-CN/tutorials/godot-complete-project` - Godot 完整项目
|
||||
- `/zh-CN/tutorials/functional-programming` - 函数式编程实践
|
||||
- `/zh-CN/tutorials/pause-system` - 暂停系统实现
|
||||
- `/zh-CN/tutorials/data-migration` - 数据迁移实践
|
||||
- `/zh-CN/tutorials/godot-integration` - Godot 集成
|
||||
- `/zh-CN/tutorials/advanced-patterns` - 高级模式
|
||||
|
||||
**其他**:
|
||||
- `/zh-CN/getting-started/quick-start` - 快速开始
|
||||
- `/zh-CN/getting-started/installation` - 安装指南
|
||||
- `/zh-CN/best-practices/architecture-patterns` - 架构模式
|
||||
|
||||
**不存在的路径** (不要链接):
|
||||
- `/zh-CN/best-practices/performance` - 尚未创建
|
||||
- `/zh-CN/core/serializer` - 错误路径,应使用 `/zh-CN/game/serialization`
|
||||
|
||||
## 代码块规范
|
||||
|
||||
### 1. 代码块语言标识
|
||||
|
||||
始终指定代码块的语言:
|
||||
|
||||
```markdown
|
||||
\`\`\`csharp
|
||||
public class Example { }
|
||||
\`\`\`
|
||||
|
||||
\`\`\`bash
|
||||
npm install
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### 2. 代码注释
|
||||
|
||||
代码示例应包含中文注释:
|
||||
|
||||
```csharp
|
||||
// 创建玩家实体
|
||||
var player = new Player
|
||||
{
|
||||
Name = "玩家1", // 玩家名称
|
||||
Level = 1 // 初始等级
|
||||
};
|
||||
```
|
||||
|
||||
## Frontmatter 规范
|
||||
|
||||
每个文档必须包含正确的 frontmatter:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: 文档标题
|
||||
description: 简短描述(1-2 句话)
|
||||
---
|
||||
```
|
||||
|
||||
## 文档结构规范
|
||||
|
||||
### 指南文档结构
|
||||
|
||||
1. 概述
|
||||
2. 核心概念
|
||||
3. 基本用法
|
||||
4. 高级用法
|
||||
5. 最佳实践
|
||||
6. 常见问题
|
||||
7. 相关文档
|
||||
|
||||
### 教程文档结构
|
||||
|
||||
1. 学习目标
|
||||
2. 前置条件
|
||||
3. 步骤 1-N (3-7 步)
|
||||
4. 完整代码
|
||||
5. 运行结果
|
||||
6. 下一步
|
||||
7. 相关文档
|
||||
|
||||
## 验证清单
|
||||
|
||||
生成文档后,必须检查:
|
||||
|
||||
- [ ] 所有泛型标记已转义 (`<T>` → `<T>`)
|
||||
- [ ] 所有内部链接指向存在的页面
|
||||
- [ ] Frontmatter 格式正确
|
||||
- [ ] 代码块指定了语言
|
||||
- [ ] 代码包含中文注释
|
||||
- [ ] 文档结构完整
|
||||
- [ ] 没有 HTML 标签错误
|
||||
|
||||
## 自动修复脚本
|
||||
|
||||
如果文档已生成,可以使用以下脚本修复常见问题:
|
||||
|
||||
```bash
|
||||
# 修复泛型标记
|
||||
sed -i 's/<T>/\<T\>/g' file.md
|
||||
sed -i 's/<TResult>/\<TResult\>/g' file.md
|
||||
sed -i 's/<TValue>/\<TValue\>/g' file.md
|
||||
sed -i 's/<TError>/\<TError\>/g' file.md
|
||||
|
||||
# 验证构建
|
||||
cd docs && bun run build
|
||||
```
|
||||
@ -1,84 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 共享的模块配置
|
||||
# 用于统一管理 GFramework 项目的模块映射关系
|
||||
|
||||
# 根据模块名获取源代码目录
|
||||
get_source_dir() {
|
||||
local MODULE="$1"
|
||||
case "$MODULE" in
|
||||
Core)
|
||||
echo "GFramework.Core"
|
||||
;;
|
||||
Game)
|
||||
echo "GFramework.Game"
|
||||
;;
|
||||
Godot)
|
||||
echo "GFramework.Godot"
|
||||
;;
|
||||
SourceGenerators)
|
||||
echo "GFramework.SourceGenerators"
|
||||
;;
|
||||
*)
|
||||
echo ""
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 根据模块名获取文档输出目录
|
||||
get_docs_dir() {
|
||||
local MODULE="$1"
|
||||
case "$MODULE" in
|
||||
Core)
|
||||
echo "docs/zh-CN/api-reference/core"
|
||||
;;
|
||||
Game)
|
||||
echo "docs/zh-CN/api-reference/game"
|
||||
;;
|
||||
Godot)
|
||||
echo "docs/zh-CN/api-reference/godot"
|
||||
;;
|
||||
SourceGenerators)
|
||||
echo "docs/zh-CN/api-reference/source-generators"
|
||||
;;
|
||||
*)
|
||||
echo ""
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 根据命名空间推断模块名
|
||||
infer_module_from_namespace() {
|
||||
local NAMESPACE="$1"
|
||||
if [[ "$NAMESPACE" == GFramework.Core* ]]; then
|
||||
echo "Core"
|
||||
elif [[ "$NAMESPACE" == GFramework.Game* ]]; then
|
||||
echo "Game"
|
||||
elif [[ "$NAMESPACE" == GFramework.Godot* ]]; then
|
||||
echo "Godot"
|
||||
elif [[ "$NAMESPACE" == GFramework.SourceGenerators* ]]; then
|
||||
echo "SourceGenerators"
|
||||
else
|
||||
echo ""
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 获取所有可用模块列表
|
||||
get_all_modules() {
|
||||
echo "Core Game Godot SourceGenerators"
|
||||
}
|
||||
|
||||
# 验证模块名是否有效
|
||||
is_valid_module() {
|
||||
local MODULE="$1"
|
||||
case "$MODULE" in
|
||||
Core|Game|Godot|SourceGenerators)
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@ -1,121 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 生成代码示例辅助脚本
|
||||
# 用法: generate-examples.sh <类型> <类名> [命名空间]
|
||||
|
||||
set -e
|
||||
|
||||
TYPE="$1" # class/interface/enum
|
||||
CLASS_NAME="$2"
|
||||
NAMESPACE="$3"
|
||||
|
||||
if [ -z "$TYPE" ] || [ -z "$CLASS_NAME" ]; then
|
||||
echo "用法: $0 <类型> <类名> [命名空间]"
|
||||
echo "类型: class, interface, enum"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=========================================="
|
||||
echo "代码示例生成指南"
|
||||
echo "=========================================="
|
||||
echo "类型: $TYPE"
|
||||
echo "类名: $CLASS_NAME"
|
||||
if [ -n "$NAMESPACE" ]; then
|
||||
echo "命名空间: $NAMESPACE"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 根据类型提供示例生成指南
|
||||
case "$TYPE" in
|
||||
class)
|
||||
echo "## 类示例生成建议"
|
||||
echo ""
|
||||
echo "1. 基本用法示例:"
|
||||
echo " - 实例化对象"
|
||||
echo " - 调用主要方法"
|
||||
echo " - 访问公共属性"
|
||||
echo ""
|
||||
echo "2. 常见场景示例:"
|
||||
echo " - 实际应用案例"
|
||||
echo " - 与其他组件的集成"
|
||||
echo ""
|
||||
echo "3. 高级用法示例(如适用):"
|
||||
echo " - 复杂配置"
|
||||
echo " - 扩展和自定义"
|
||||
echo ""
|
||||
echo "示例模板:"
|
||||
echo '```csharp'
|
||||
echo "// 创建实例"
|
||||
echo "var instance = new $CLASS_NAME();"
|
||||
echo ""
|
||||
echo "// 使用主要功能"
|
||||
echo "instance.MainMethod();"
|
||||
echo '```'
|
||||
;;
|
||||
interface)
|
||||
echo "## 接口示例生成建议"
|
||||
echo ""
|
||||
echo "1. 实现接口:"
|
||||
echo " - 展示如何实现该接口"
|
||||
echo " - 实现所有必需成员"
|
||||
echo ""
|
||||
echo "2. 使用接口:"
|
||||
echo " - 通过接口类型使用实例"
|
||||
echo " - 依赖注入场景"
|
||||
echo ""
|
||||
echo "示例模板:"
|
||||
echo '```csharp'
|
||||
echo "// 实现接口"
|
||||
echo "public class My$CLASS_NAME : $CLASS_NAME"
|
||||
echo "{"
|
||||
echo " // 实现成员"
|
||||
echo "}"
|
||||
echo ""
|
||||
echo "// 使用接口"
|
||||
echo "$CLASS_NAME instance = new My$CLASS_NAME();"
|
||||
echo '```'
|
||||
;;
|
||||
enum)
|
||||
echo "## 枚举示例生成建议"
|
||||
echo ""
|
||||
echo "1. 基本用法:"
|
||||
echo " - 枚举值赋值"
|
||||
echo " - 值比较"
|
||||
echo ""
|
||||
echo "2. Switch 语句:"
|
||||
echo " - 根据枚举值执行不同逻辑"
|
||||
echo ""
|
||||
echo "3. 枚举转换:"
|
||||
echo " - 字符串转枚举"
|
||||
echo " - 枚举转整数"
|
||||
echo ""
|
||||
echo "示例模板:"
|
||||
echo '```csharp'
|
||||
echo "// 使用枚举值"
|
||||
echo "var value = $CLASS_NAME.SomeValue;"
|
||||
echo ""
|
||||
echo "// Switch 语句"
|
||||
echo "switch (value)"
|
||||
echo "{"
|
||||
echo " case $CLASS_NAME.Value1:"
|
||||
echo " // 处理逻辑"
|
||||
echo " break;"
|
||||
echo " case $CLASS_NAME.Value2:"
|
||||
echo " // 处理逻辑"
|
||||
echo " break;"
|
||||
echo "}"
|
||||
echo '```'
|
||||
;;
|
||||
*)
|
||||
echo "错误: 不支持的类型: $TYPE"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
echo "注意事项:"
|
||||
echo "- 使用项目的命名约定"
|
||||
echo "- 包含必要的 using 语句"
|
||||
echo "- 确保示例代码可以编译运行"
|
||||
echo "- 参考现有教程的代码风格"
|
||||
|
||||
exit 0
|
||||
@ -1,48 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 解析 C# XML 文档注释
|
||||
# 用法: parse-csharp-xml.sh <C# 文件路径>
|
||||
|
||||
set -e
|
||||
|
||||
FILE_PATH="$1"
|
||||
|
||||
if [ -z "$FILE_PATH" ]; then
|
||||
echo "用法: $0 <C# 文件路径>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$FILE_PATH" ]; then
|
||||
echo "错误: 文件不存在: $FILE_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "解析 C# XML 文档注释: $FILE_PATH"
|
||||
|
||||
# 提取 summary 标签内容
|
||||
echo "=== Summary ==="
|
||||
grep -A 5 "/// <summary>" "$FILE_PATH" | grep "///" | sed 's/.*\/\/\/\s*//' | sed 's/<summary>//g' | sed 's/<\/summary>//g' || echo "未找到 summary"
|
||||
|
||||
# 提取 param 标签内容
|
||||
echo ""
|
||||
echo "=== Parameters ==="
|
||||
grep "/// <param" "$FILE_PATH" | sed 's/.*\/\/\/\s*//' || echo "未找到 param"
|
||||
|
||||
# 提取 returns 标签内容
|
||||
echo ""
|
||||
echo "=== Returns ==="
|
||||
grep "/// <returns>" "$FILE_PATH" | sed 's/.*\/\/\/\s*//' | sed 's/<returns>//g' | sed 's/<\/returns>//g' || echo "未找到 returns"
|
||||
|
||||
# 提取 exception 标签内容
|
||||
echo ""
|
||||
echo "=== Exceptions ==="
|
||||
grep "/// <exception" "$FILE_PATH" | sed 's/.*\/\/\/\s*//' || echo "未找到 exception"
|
||||
|
||||
# 提取 example 标签内容
|
||||
echo ""
|
||||
echo "=== Examples ==="
|
||||
grep -A 10 "/// <example>" "$FILE_PATH" | grep "///" | sed 's/.*\/\/\/\s*//' || echo "未找到 example"
|
||||
|
||||
echo ""
|
||||
echo "解析完成"
|
||||
|
||||
exit 0
|
||||
@ -1,57 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 更新 VitePress 侧边栏配置
|
||||
# 用法: update-vitepress-nav.sh <文档路径> <文档标题>
|
||||
|
||||
set -e
|
||||
|
||||
DOC_PATH="$1"
|
||||
DOC_TITLE="$2"
|
||||
CONFIG_FILE="docs/.vitepress/config.mts"
|
||||
|
||||
if [ -z "$DOC_PATH" ] || [ -z "$DOC_TITLE" ]; then
|
||||
echo "用法: $0 <文档路径> <文档标题>"
|
||||
echo "示例: $0 /zh-CN/api-reference/core/architecture Architecture"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$CONFIG_FILE" ]; then
|
||||
echo "错误: 找不到 VitePress 配置文件: $CONFIG_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 提取模块名称(core/game/godot/source-generators)
|
||||
MODULE=$(echo "$DOC_PATH" | grep -oP '(?<=/zh-CN/)[^/]+' | head -1)
|
||||
|
||||
if [ -z "$MODULE" ]; then
|
||||
echo "错误: 无法从路径中提取模块名称: $DOC_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=========================================="
|
||||
echo "VitePress 导航配置更新"
|
||||
echo "=========================================="
|
||||
echo "模块: $MODULE"
|
||||
echo "路径: $DOC_PATH"
|
||||
echo "标题: $DOC_TITLE"
|
||||
echo ""
|
||||
|
||||
# 检查配置文件中是否已存在该路径
|
||||
if grep -q "link: '$DOC_PATH'" "$CONFIG_FILE"; then
|
||||
echo "✓ 该文档已存在于导航配置中"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "提示: 需要在 VitePress 配置中添加新条目"
|
||||
echo ""
|
||||
echo "建议的配置条目:"
|
||||
echo "{ text: '$DOC_TITLE', link: '$DOC_PATH' }"
|
||||
echo ""
|
||||
echo "请使用以下方式之一更新配置:"
|
||||
echo "1. 让 AI 使用 Edit 工具直接修改 $CONFIG_FILE"
|
||||
echo "2. 手动编辑配置文件并添加上述条目到对应的 sidebar 部分"
|
||||
echo ""
|
||||
|
||||
# 输出相关的 sidebar 配置路径
|
||||
echo "相关的 sidebar 配置路径: '/zh-CN/$MODULE/'"
|
||||
|
||||
exit 0
|
||||
@ -1,210 +0,0 @@
|
||||
# VitePress API 文档生成
|
||||
|
||||
为单个 C# 类、接口或枚举生成符合 VitePress 标准的 API 参考文档。
|
||||
|
||||
## 用途
|
||||
|
||||
此 skill 用于从 C# 源代码文件自动生成结构化的 API 文档,包括:
|
||||
- 类型概述和命名空间信息
|
||||
- 构造函数、方法、属性的详细说明
|
||||
- 基于 XML 文档注释的描述
|
||||
- 自动生成的使用示例
|
||||
- 相关类型的交叉引用
|
||||
|
||||
## 调用方式
|
||||
|
||||
```bash
|
||||
/vitepress-api-doc <C# 文件路径>
|
||||
```
|
||||
|
||||
**示例**:
|
||||
```bash
|
||||
/vitepress-api-doc GFramework.Core/architecture/Architecture.cs
|
||||
```
|
||||
|
||||
## 工作流程
|
||||
|
||||
1. **读取源代码文件**
|
||||
- 验证文件存在且为 C# 文件
|
||||
- 读取完整的源代码内容
|
||||
|
||||
2. **解析代码结构**
|
||||
- 提取命名空间、类名、访问修饰符
|
||||
- 识别类型(class/interface/enum/struct)
|
||||
- 解析继承关系和实现的接口
|
||||
- 提取所有公共成员(构造函数、方法、属性、事件、字段)
|
||||
|
||||
3. **提取 XML 文档注释**
|
||||
- 解析 `/// <summary>` 标签(类型和成员描述)
|
||||
- 解析 `/// <param>` 标签(参数说明)
|
||||
- 解析 `/// <returns>` 标签(返回值说明)
|
||||
- 解析 `/// <exception>` 标签(异常说明)
|
||||
- 解析 `/// <example>` 标签(示例代码)
|
||||
- 解析 `/// <see cref=""/>` 标签(交叉引用)
|
||||
|
||||
4. **生成 Markdown 文档**
|
||||
- 根据 `template.md` 填充内容
|
||||
- 转义泛型符号(`<T>` → `<T>`)
|
||||
- 生成使用示例(基于 API 签名)
|
||||
- 添加相关文档链接
|
||||
|
||||
5. **确定输出路径**
|
||||
- 根据命名空间确定模块(Core/Game/Godot/SourceGenerators)
|
||||
- 输出到 `docs/zh-CN/api-reference/<模块>/<类名>.md`
|
||||
|
||||
6. **更新 VitePress 配置**
|
||||
- 调用共享脚本 `update-vitepress-nav.sh`
|
||||
- 在侧边栏配置中添加新文档条目
|
||||
|
||||
7. **验证文档质量**
|
||||
- 检查 Frontmatter 格式
|
||||
- 验证内部链接
|
||||
- 确保代码块语法正确
|
||||
|
||||
## 输出规范
|
||||
|
||||
### Frontmatter 格式
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: 类名
|
||||
description: 从 XML <summary> 提取的简短描述
|
||||
outline: deep
|
||||
---
|
||||
```
|
||||
|
||||
### 文档结构
|
||||
|
||||
1. **标题**:使用类名作为一级标题
|
||||
2. **概述**:XML summary 内容
|
||||
3. **命名空间和程序集信息**
|
||||
4. **继承链**(如果适用)
|
||||
5. **构造函数**(如果有)
|
||||
6. **公共方法**(按字母顺序)
|
||||
7. **公共属性**(按字母顺序)
|
||||
8. **公共事件**(如果有)
|
||||
9. **使用示例**(自动生成)
|
||||
10. **另请参阅**(相关类型链接)
|
||||
|
||||
### 代码块格式
|
||||
|
||||
所有 C# 代码块必须使用:
|
||||
```markdown
|
||||
\`\`\`csharp
|
||||
// 代码内容
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### 泛型符号转义
|
||||
|
||||
- `List<T>` → `List<T>`
|
||||
- `Dictionary<K, V>` → `Dictionary<K, V>`
|
||||
- `IEnumerable<T>` → `IEnumerable<T>`
|
||||
|
||||
### 内部链接格式
|
||||
|
||||
- 相对路径:`[Architecture](./architecture.md)`
|
||||
- 绝对路径:`[Core 架构](/zh-CN/core/architecture)`
|
||||
- 锚点链接:`[构造函数](#构造函数)`
|
||||
|
||||
## 前置条件
|
||||
|
||||
1. 项目必须有 VitePress 配置文件(`docs/.vitepress/config.mts`)
|
||||
2. 目标 C# 文件必须存在且可读
|
||||
3. C# 文件必须包含 XML 文档注释(`///`)
|
||||
4. 文件必须包含至少一个公共类型
|
||||
|
||||
## 配置选项
|
||||
|
||||
### 自动检测模块
|
||||
|
||||
根据命名空间自动确定模块:
|
||||
- `GFramework.Core.*` → `core`
|
||||
- `GFramework.Game.*` → `game`
|
||||
- `GFramework.Godot.*` → `godot`
|
||||
- `GFramework.SourceGenerators.*` → `source-generators`
|
||||
|
||||
### 示例生成策略
|
||||
|
||||
- **基本用法**:最简单的 API 调用
|
||||
- **常见场景**:实际应用案例
|
||||
- **高级用法**:复杂配置(如果适用)
|
||||
|
||||
## 示例输出
|
||||
|
||||
参考 `examples/` 目录中的示例文档:
|
||||
- `class-example.md` - 类文档示例
|
||||
- `interface-example.md` - 接口文档示例
|
||||
- `enum-example.md` - 枚举文档示例
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **仅使用 XML 注释**:不对缺失的注释进行 AI 补充
|
||||
2. **仅提取公共成员**:忽略 `internal`、`private`、`protected` 成员
|
||||
3. **保持文档同步**:文档内容直接来源于代码,确保准确性
|
||||
4. **遵循项目风格**:参考现有文档的格式和术语
|
||||
|
||||
## 相关 Skills
|
||||
|
||||
- `/vitepress-validate` - 验证生成的文档质量
|
||||
- `/vitepress-batch-api` - 批量生成整个模块的 API 文档
|
||||
|
||||
## 技术细节
|
||||
|
||||
### XML 注释标签映射
|
||||
|
||||
| XML 标签 | Markdown 输出 |
|
||||
|---------|--------------|
|
||||
| `<summary>` | 概述章节 |
|
||||
| `<param name="x">` | 参数列表 |
|
||||
| `<returns>` | 返回值说明 |
|
||||
| `<exception cref="T">` | 异常列表 |
|
||||
| `<example>` | 示例代码块 |
|
||||
| `<see cref="T"/>` | 内部链接 |
|
||||
| `<remarks>` | 备注章节 |
|
||||
|
||||
### 成员签名格式
|
||||
|
||||
**方法**:
|
||||
```markdown
|
||||
### MethodName
|
||||
|
||||
描述内容
|
||||
|
||||
**签名**:
|
||||
\`\`\`csharp
|
||||
public ReturnType MethodName(ParamType param)
|
||||
\`\`\`
|
||||
|
||||
**参数**:
|
||||
- `param` (ParamType): 参数说明
|
||||
|
||||
**返回值**:
|
||||
- (ReturnType): 返回值说明
|
||||
```
|
||||
|
||||
**属性**:
|
||||
```markdown
|
||||
### PropertyName
|
||||
|
||||
描述内容
|
||||
|
||||
**类型**:`PropertyType`
|
||||
|
||||
**访问**:get / set
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 问题:找不到 XML 注释
|
||||
**解决方案**:确保 C# 文件包含 `///` 注释,而不是 `//` 或 `/* */`
|
||||
|
||||
### 问题:泛型符号显示错误
|
||||
**解决方案**:VitePress 配置中已包含 `safeGenericEscapePlugin`,确保正确转义
|
||||
|
||||
### 问题:侧边栏未更新
|
||||
**解决方案**:检查 `update-vitepress-nav.sh` 脚本是否正确执行
|
||||
|
||||
## 版本历史
|
||||
|
||||
- v1.0.0 - 初始版本,支持类、接口、枚举的文档生成
|
||||
@ -1,252 +0,0 @@
|
||||
---
|
||||
title: Architecture
|
||||
description: 架构基类,提供系统、模型、工具等组件的注册与管理功能。专注于生命周期管理、初始化流程控制和架构阶段转换。
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Architecture
|
||||
|
||||
## 概述
|
||||
|
||||
架构基类,提供系统、模型、工具等组件的注册与管理功能。专注于生命周期管理、初始化流程控制和架构阶段转换。
|
||||
|
||||
**命名空间**:`GFramework.Core.architecture`
|
||||
**程序集**:`GFramework.Core`
|
||||
**继承**:`Object` → `Architecture`
|
||||
**实现**:`IArchitecture`
|
||||
|
||||
## 构造函数
|
||||
|
||||
### Architecture
|
||||
|
||||
创建架构实例。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
public Architecture(
|
||||
IArchitectureConfiguration? configuration = null,
|
||||
IEnvironment? environment = null,
|
||||
IArchitectureServices? services = null,
|
||||
IArchitectureContext? context = null
|
||||
)
|
||||
```
|
||||
|
||||
**参数**:
|
||||
- `configuration` (IArchitectureConfiguration?): 架构配置对象,为 null 时使用默认配置
|
||||
- `environment` (IEnvironment?): 环境配置对象,为 null 时使用默认环境
|
||||
- `services` (IArchitectureServices?): 架构服务对象,为 null 时创建新实例
|
||||
- `context` (IArchitectureContext?): 架构上下文对象,为 null 时创建新实例
|
||||
|
||||
## 公共方法
|
||||
|
||||
### Initialize
|
||||
|
||||
同步初始化架构,阻塞当前线程直到初始化完成。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
public void Initialize()
|
||||
```
|
||||
|
||||
**特点**:
|
||||
- 阻塞式初始化
|
||||
- 适用于简单场景或控制台应用
|
||||
- 初始化失败时抛出异常并进入 `FailedInitialization` 阶段
|
||||
|
||||
### InitializeAsync
|
||||
|
||||
异步初始化架构,返回 Task 以便调用者可以等待初始化完成。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
public async Task InitializeAsync()
|
||||
```
|
||||
|
||||
**返回值**:
|
||||
- (Task): 表示异步初始化操作的任务
|
||||
|
||||
**特点**:
|
||||
- 非阻塞式初始化
|
||||
- 支持异步组件初始化
|
||||
- 适用于需要异步加载资源的场景
|
||||
|
||||
### InstallModule
|
||||
|
||||
安装架构模块,用于扩展架构功能。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
public IArchitectureModule InstallModule(IArchitectureModule module)
|
||||
```
|
||||
|
||||
**参数**:
|
||||
- `module` (IArchitectureModule): 要安装的模块实例
|
||||
|
||||
**返回值**:
|
||||
- (IArchitectureModule): 返回安装的模块实例
|
||||
|
||||
### RegisterSystem
|
||||
|
||||
注册系统组件到架构中。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
public void RegisterSystem<TSystem>(TSystem system) where TSystem : ISystem
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `TSystem`: 系统类型,必须实现 ISystem 接口
|
||||
|
||||
**参数**:
|
||||
- `system` (TSystem): 要注册的系统实例
|
||||
|
||||
### RegisterModel
|
||||
|
||||
注册模型组件到架构中。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
public void RegisterModel<TModel>(TModel model) where TModel : IModel
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `TModel`: 模型类型,必须实现 IModel 接口
|
||||
|
||||
**参数**:
|
||||
- `model` (TModel): 要注册的模型实例
|
||||
|
||||
### RegisterUtility
|
||||
|
||||
注册工具组件到架构中。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
public void RegisterUtility<TUtility>(TUtility utility) where TUtility : IUtility
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `TUtility`: 工具类型,必须实现 IUtility 接口
|
||||
|
||||
**参数**:
|
||||
- `utility` (TUtility): 要注册的工具实例
|
||||
|
||||
### SendCommand
|
||||
|
||||
发送并执行命令。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
public void SendCommand(ICommand command)
|
||||
```
|
||||
|
||||
**参数**:
|
||||
- `command` (ICommand): 要执行的命令实例
|
||||
|
||||
### SendCommand<TResult>
|
||||
|
||||
发送并执行带返回值的命令。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
public TResult SendCommand<TResult>(ICommand<TResult> command)
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `TResult`: 命令返回值类型
|
||||
|
||||
**参数**:
|
||||
- `command` (ICommand<TResult>): 要执行的命令实例
|
||||
|
||||
**返回值**:
|
||||
- (TResult): 命令执行结果
|
||||
|
||||
## 公共属性
|
||||
|
||||
### CurrentPhase
|
||||
|
||||
获取当前架构的阶段。
|
||||
|
||||
**类型**:`ArchitecturePhase`
|
||||
**访问**:get
|
||||
|
||||
### Context
|
||||
|
||||
获取架构上下文,提供对架构服务的访问。
|
||||
|
||||
**类型**:`IArchitectureContext`
|
||||
**访问**:get
|
||||
|
||||
### IsReady
|
||||
|
||||
获取一个布尔值,指示当前架构是否处于就绪状态。
|
||||
|
||||
**类型**:`bool`
|
||||
**访问**:get
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 基本用法
|
||||
|
||||
```csharp
|
||||
// 1. 定义你的架构(继承 Architecture 基类)
|
||||
public class GameArchitecture : Architecture
|
||||
{
|
||||
protected override void Init()
|
||||
{
|
||||
// 注册 Model
|
||||
RegisterModel(new PlayerModel());
|
||||
RegisterModel(new InventoryModel());
|
||||
|
||||
// 注册 System
|
||||
RegisterSystem(new GameplaySystem());
|
||||
RegisterSystem(new SaveSystem());
|
||||
|
||||
// 注册 Utility
|
||||
RegisterUtility(new StorageUtility());
|
||||
RegisterUtility(new TimeUtility());
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 创建并初始化架构
|
||||
var architecture = new GameArchitecture();
|
||||
architecture.Initialize();
|
||||
|
||||
// 3. 等待架构就绪
|
||||
await architecture.WaitUntilReadyAsync();
|
||||
```
|
||||
|
||||
### 异步初始化
|
||||
|
||||
```csharp
|
||||
var architecture = new GameArchitecture();
|
||||
await architecture.InitializeAsync(); // 异步等待初始化完成
|
||||
|
||||
// 检查架构是否已就绪
|
||||
if (architecture.IsReady)
|
||||
{
|
||||
Console.WriteLine("架构已就绪,可以开始游戏");
|
||||
}
|
||||
```
|
||||
|
||||
### 使用自定义配置
|
||||
|
||||
```csharp
|
||||
var config = new ArchitectureConfiguration
|
||||
{
|
||||
ArchitectureProperties = new ArchitectureProperties
|
||||
{
|
||||
StrictPhaseValidation = true, // 启用严格阶段验证
|
||||
AllowLateRegistration = false // 禁止就绪后注册组件
|
||||
}
|
||||
};
|
||||
|
||||
var architecture = new GameArchitecture(configuration: config);
|
||||
architecture.Initialize();
|
||||
```
|
||||
|
||||
## 另请参阅
|
||||
|
||||
- [IArchitecture](./iarchitecture.md) - 架构接口
|
||||
- [ArchitecturePhase](./architecture-phase.md) - 架构阶段枚举
|
||||
- [IArchitectureModule](./iarchitecture-module.md) - 架构模块接口
|
||||
- [架构组件](/zh-CN/core/architecture) - 架构使用指南
|
||||
@ -1,193 +0,0 @@
|
||||
---
|
||||
title: ArchitecturePhase
|
||||
description: 架构阶段枚举,定义了架构生命周期的各个阶段。
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# ArchitecturePhase
|
||||
|
||||
## 概述
|
||||
|
||||
架构阶段枚举,定义了架构生命周期的各个阶段。
|
||||
|
||||
**命名空间**:`GFramework.Core.Abstractions.enums`
|
||||
**程序集**:`GFramework.Core.Abstractions`
|
||||
**基础类型**:`Enum`
|
||||
|
||||
## 枚举值
|
||||
|
||||
### None
|
||||
|
||||
初始阶段,架构尚未开始初始化。
|
||||
|
||||
**值**:`0`
|
||||
|
||||
### BeforeUtilityInit
|
||||
|
||||
工具初始化前阶段。
|
||||
|
||||
**值**:`1`
|
||||
|
||||
### AfterUtilityInit
|
||||
|
||||
工具初始化后阶段。
|
||||
|
||||
**值**:`2`
|
||||
|
||||
### BeforeModelInit
|
||||
|
||||
模型初始化前阶段。
|
||||
|
||||
**值**:`3`
|
||||
|
||||
### AfterModelInit
|
||||
|
||||
模型初始化后阶段。
|
||||
|
||||
**值**:`4`
|
||||
|
||||
### BeforeSystemInit
|
||||
|
||||
系统初始化前阶段。
|
||||
|
||||
**值**:`5`
|
||||
|
||||
### AfterSystemInit
|
||||
|
||||
系统初始化后阶段。
|
||||
|
||||
**值**:`6`
|
||||
|
||||
### Ready
|
||||
|
||||
就绪状态,架构已完全初始化并可以使用。
|
||||
|
||||
**值**:`7`
|
||||
|
||||
### FailedInitialization
|
||||
|
||||
初始化失败状态。
|
||||
|
||||
**值**:`8`
|
||||
|
||||
### Destroying
|
||||
|
||||
正在销毁阶段。
|
||||
|
||||
**值**:`9`
|
||||
|
||||
### Destroyed
|
||||
|
||||
已销毁阶段。
|
||||
|
||||
**值**:`10`
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 检查架构阶段
|
||||
|
||||
```csharp
|
||||
var architecture = new GameArchitecture();
|
||||
architecture.Initialize();
|
||||
|
||||
// 检查架构是否已就绪
|
||||
if (architecture.CurrentPhase == ArchitecturePhase.Ready)
|
||||
{
|
||||
Console.WriteLine("架构已就绪,可以开始游戏");
|
||||
}
|
||||
```
|
||||
|
||||
### 监听阶段变化
|
||||
|
||||
```csharp
|
||||
public class PhaseMonitor : IArchitectureLifecycle
|
||||
{
|
||||
public void OnPhase(ArchitecturePhase phase, IArchitecture architecture)
|
||||
{
|
||||
switch (phase)
|
||||
{
|
||||
case ArchitecturePhase.BeforeUtilityInit:
|
||||
Console.WriteLine("开始初始化工具");
|
||||
break;
|
||||
case ArchitecturePhase.AfterUtilityInit:
|
||||
Console.WriteLine("工具初始化完成");
|
||||
break;
|
||||
case ArchitecturePhase.BeforeModelInit:
|
||||
Console.WriteLine("开始初始化模型");
|
||||
break;
|
||||
case ArchitecturePhase.AfterModelInit:
|
||||
Console.WriteLine("模型初始化完成");
|
||||
break;
|
||||
case ArchitecturePhase.BeforeSystemInit:
|
||||
Console.WriteLine("开始初始化系统");
|
||||
break;
|
||||
case ArchitecturePhase.AfterSystemInit:
|
||||
Console.WriteLine("系统初始化完成");
|
||||
break;
|
||||
case ArchitecturePhase.Ready:
|
||||
Console.WriteLine("架构就绪");
|
||||
break;
|
||||
case ArchitecturePhase.FailedInitialization:
|
||||
Console.WriteLine("架构初始化失败");
|
||||
break;
|
||||
case ArchitecturePhase.Destroying:
|
||||
Console.WriteLine("架构正在销毁");
|
||||
break;
|
||||
case ArchitecturePhase.Destroyed:
|
||||
Console.WriteLine("架构已销毁");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 注册监听器
|
||||
var architecture = new GameArchitecture();
|
||||
architecture.RegisterLifecycleHook(new PhaseMonitor());
|
||||
architecture.Initialize();
|
||||
```
|
||||
|
||||
### 等待特定阶段
|
||||
|
||||
```csharp
|
||||
public async Task WaitForReady(IArchitecture architecture)
|
||||
{
|
||||
while (architecture.CurrentPhase != ArchitecturePhase.Ready)
|
||||
{
|
||||
if (architecture.CurrentPhase == ArchitecturePhase.FailedInitialization)
|
||||
{
|
||||
throw new Exception("架构初始化失败");
|
||||
}
|
||||
|
||||
await Task.Delay(100);
|
||||
}
|
||||
|
||||
Console.WriteLine("架构已就绪");
|
||||
}
|
||||
```
|
||||
|
||||
## 阶段转换顺序
|
||||
|
||||
正常初始化流程的阶段转换顺序:
|
||||
|
||||
1. `None` → `BeforeUtilityInit`
|
||||
2. `BeforeUtilityInit` → `AfterUtilityInit`
|
||||
3. `AfterUtilityInit` → `BeforeModelInit`
|
||||
4. `BeforeModelInit` → `AfterModelInit`
|
||||
5. `AfterModelInit` → `BeforeSystemInit`
|
||||
6. `BeforeSystemInit` → `AfterSystemInit`
|
||||
7. `AfterSystemInit` → `Ready`
|
||||
|
||||
销毁流程的阶段转换顺序:
|
||||
|
||||
1. `Ready` → `Destroying`
|
||||
2. `Destroying` → `Destroyed`
|
||||
|
||||
异常流程:
|
||||
|
||||
- 任何阶段 → `FailedInitialization`(初始化过程中发生异常)
|
||||
|
||||
## 另请参阅
|
||||
|
||||
- [Architecture](./architecture.md) - 架构基类
|
||||
- [IArchitectureLifecycle](./iarchitecture-lifecycle.md) - 生命周期钩子接口
|
||||
- [架构组件](/zh-CN/core/architecture) - 架构使用指南
|
||||
@ -1,290 +0,0 @@
|
||||
---
|
||||
title: IArchitecture
|
||||
description: 架构接口,定义了框架的核心功能契约。
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# IArchitecture
|
||||
|
||||
## 概述
|
||||
|
||||
架构接口,定义了框架的核心功能契约。
|
||||
|
||||
**命名空间**:`GFramework.Core.Abstractions.architecture`
|
||||
**程序集**:`GFramework.Core.Abstractions`
|
||||
**实现类**:[Architecture](./architecture.md)
|
||||
|
||||
## 公共方法
|
||||
|
||||
### RegisterSystem<TSystem>
|
||||
|
||||
注册系统组件到架构中。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
void RegisterSystem<TSystem>(TSystem system) where TSystem : ISystem
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `TSystem`: 系统类型,必须实现 ISystem 接口
|
||||
|
||||
**参数**:
|
||||
- `system` (TSystem): 要注册的系统实例
|
||||
|
||||
### RegisterModel<TModel>
|
||||
|
||||
注册模型组件到架构中。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
void RegisterModel<TModel>(TModel model) where TModel : IModel
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `TModel`: 模型类型,必须实现 IModel 接口
|
||||
|
||||
**参数**:
|
||||
- `model` (TModel): 要注册的模型实例
|
||||
|
||||
### RegisterUtility<TUtility>
|
||||
|
||||
注册工具组件到架构中。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
void RegisterUtility<TUtility>(TUtility utility) where TUtility : IUtility
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `TUtility`: 工具类型,必须实现 IUtility 接口
|
||||
|
||||
**参数**:
|
||||
- `utility` (TUtility): 要注册的工具实例
|
||||
|
||||
### GetModel<T>
|
||||
|
||||
从容器中获取已注册的模型。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
T GetModel<T>() where T : class, IModel
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `T`: 模型类型
|
||||
|
||||
**返回值**:
|
||||
- (T): 模型实例
|
||||
|
||||
### GetSystem<T>
|
||||
|
||||
从容器中获取已注册的系统。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
T GetSystem<T>() where T : class, ISystem
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `T`: 系统类型
|
||||
|
||||
**返回值**:
|
||||
- (T): 系统实例
|
||||
|
||||
### GetUtility<T>
|
||||
|
||||
从容器中获取已注册的工具。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
T GetUtility<T>() where T : class, IUtility
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `T`: 工具类型
|
||||
|
||||
**返回值**:
|
||||
- (T): 工具实例
|
||||
|
||||
### SendCommand
|
||||
|
||||
发送并执行命令。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
void SendCommand(ICommand command)
|
||||
```
|
||||
|
||||
**参数**:
|
||||
- `command` (ICommand): 要执行的命令实例
|
||||
|
||||
### SendCommand<TResult>
|
||||
|
||||
发送并执行带返回值的命令。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
TResult SendCommand<TResult>(ICommand<TResult> command)
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `TResult`: 命令返回值类型
|
||||
|
||||
**参数**:
|
||||
- `command` (ICommand<TResult>): 要执行的命令实例
|
||||
|
||||
**返回值**:
|
||||
- (TResult): 命令执行结果
|
||||
|
||||
### SendQuery<TResult>
|
||||
|
||||
发送并执行查询。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
TResult SendQuery<TResult>(IQuery<TResult> query)
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `TResult`: 查询返回值类型
|
||||
|
||||
**参数**:
|
||||
- `query` (IQuery<TResult>): 要执行的查询实例
|
||||
|
||||
**返回值**:
|
||||
- (TResult): 查询结果
|
||||
|
||||
### SendEvent<T>
|
||||
|
||||
发送事件(无参数)。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
void SendEvent<T>() where T : new()
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `T`: 事件类型,必须有无参构造函数
|
||||
|
||||
### SendEvent<T>
|
||||
|
||||
发送事件(带参数)。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
void SendEvent<T>(T e)
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `T`: 事件类型
|
||||
|
||||
**参数**:
|
||||
- `e` (T): 事件实例
|
||||
|
||||
### RegisterEvent<T>
|
||||
|
||||
注册事件监听器。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
IUnRegister RegisterEvent<T>(Action<T> onEvent)
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `T`: 事件类型
|
||||
|
||||
**参数**:
|
||||
- `onEvent` (Action<T>): 事件处理回调
|
||||
|
||||
**返回值**:
|
||||
- (IUnRegister): 用于注销事件的对象
|
||||
|
||||
### UnRegisterEvent<T>
|
||||
|
||||
注销事件监听器。
|
||||
|
||||
**签名**:
|
||||
```csharp
|
||||
void UnRegisterEvent<T>(Action<T> onEvent)
|
||||
```
|
||||
|
||||
**类型参数**:
|
||||
- `T`: 事件类型
|
||||
|
||||
**参数**:
|
||||
- `onEvent` (Action<T>): 要注销的事件处理回调
|
||||
|
||||
## 公共属性
|
||||
|
||||
### CurrentPhase
|
||||
|
||||
获取当前架构的阶段。
|
||||
|
||||
**类型**:`ArchitecturePhase`
|
||||
**访问**:get
|
||||
|
||||
### Context
|
||||
|
||||
获取架构上下文。
|
||||
|
||||
**类型**:`IArchitectureContext`
|
||||
**访问**:get
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 在 Controller 中使用
|
||||
|
||||
```csharp
|
||||
public class GameController : IController
|
||||
{
|
||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
// 获取 Model
|
||||
var playerModel = this.GetModel<PlayerModel>();
|
||||
|
||||
// 发送命令
|
||||
this.SendCommand(new StartGameCommand());
|
||||
|
||||
// 发送查询
|
||||
var score = this.SendQuery(new GetScoreQuery());
|
||||
|
||||
// 注册事件
|
||||
this.RegisterEvent<PlayerDiedEvent>(OnPlayerDied);
|
||||
}
|
||||
|
||||
private void OnPlayerDied(PlayerDiedEvent e)
|
||||
{
|
||||
// 处理玩家死亡事件
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 实现自定义架构
|
||||
|
||||
```csharp
|
||||
public class GameArchitecture : Architecture
|
||||
{
|
||||
// 单例访问
|
||||
public static IArchitecture Interface { get; private set; }
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
Interface = this;
|
||||
|
||||
// 注册组件
|
||||
RegisterModel(new PlayerModel());
|
||||
RegisterSystem(new GameplaySystem());
|
||||
RegisterUtility(new StorageUtility());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 另请参阅
|
||||
|
||||
- [Architecture](./architecture.md) - 架构基类实现
|
||||
- [IModel](./imodel.md) - 模型接口
|
||||
- [ISystem](./isystem.md) - 系统接口
|
||||
- [IUtility](./iutility.md) - 工具接口
|
||||
- [架构组件](/zh-CN/core/architecture) - 架构使用指南
|
||||
@ -1,37 +0,0 @@
|
||||
---
|
||||
title: {{CLASS_NAME}}
|
||||
description: {{XML_SUMMARY}}
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# {{CLASS_NAME}}
|
||||
|
||||
## 概述
|
||||
|
||||
{{XML_SUMMARY}}
|
||||
|
||||
**命名空间**:`{{NAMESPACE}}`
|
||||
**程序集**:`{{ASSEMBLY}}`
|
||||
{{INHERITANCE_CHAIN}}
|
||||
|
||||
## 构造函数
|
||||
|
||||
{{CONSTRUCTORS}}
|
||||
|
||||
## 公共方法
|
||||
|
||||
{{PUBLIC_METHODS}}
|
||||
|
||||
## 公共属性
|
||||
|
||||
{{PUBLIC_PROPERTIES}}
|
||||
|
||||
{{PUBLIC_EVENTS}}
|
||||
|
||||
## 使用示例
|
||||
|
||||
{{AUTO_GENERATED_EXAMPLES}}
|
||||
|
||||
## 另请参阅
|
||||
|
||||
{{RELATED_TYPES}}
|
||||
@ -1,364 +0,0 @@
|
||||
# VitePress 批量 API 文档生成
|
||||
|
||||
为整个模块批量生成 API 参考文档,提高文档生成效率。
|
||||
|
||||
## 用途
|
||||
|
||||
此 skill 用于批量生成模块的 API 文档,适用于:
|
||||
- 初始化模块文档
|
||||
- 更新整个模块的文档
|
||||
- 为新模块快速生成文档
|
||||
- 重新生成所有 API 文档
|
||||
|
||||
## 调用方式
|
||||
|
||||
```bash
|
||||
/vitepress-batch-api <模块名>
|
||||
```
|
||||
|
||||
**示例**:
|
||||
```bash
|
||||
/vitepress-batch-api Core
|
||||
/vitepress-batch-api Game
|
||||
/vitepress-batch-api Godot
|
||||
/vitepress-batch-api SourceGenerators
|
||||
```
|
||||
|
||||
## 工作流程
|
||||
|
||||
1. **扫描模块目录**
|
||||
- 根据模块名确定源代码目录
|
||||
- 递归扫描所有 C# 文件
|
||||
|
||||
2. **过滤目标文件**
|
||||
- 仅包含公共类型(public class/interface/enum/struct)
|
||||
- 排除内部类型(internal)
|
||||
- 排除生成的代码(*.g.cs、*.Designer.cs)
|
||||
- 排除测试文件(*.Tests.cs)
|
||||
|
||||
3. **批量生成文档**
|
||||
- 为每个类型调用 `/vitepress-api-doc`
|
||||
- 显示进度信息
|
||||
- 收集生成结果
|
||||
|
||||
4. **生成模块索引页**
|
||||
- 创建 `index.md` 列出所有 API
|
||||
- 按类别分组(类、接口、枚举)
|
||||
- 添加简短描述
|
||||
|
||||
5. **批量更新导航**
|
||||
- 在 VitePress 配置中添加所有新文档
|
||||
- 保持字母顺序
|
||||
- 更新模块索引
|
||||
|
||||
6. **生成摘要报告**
|
||||
- 统计生成的文档数量
|
||||
- 列出成功和失败的文件
|
||||
- 提供验证建议
|
||||
|
||||
## 输出规范
|
||||
|
||||
### 模块索引页格式
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: Core API 参考
|
||||
description: GFramework.Core 模块的 API 参考文档
|
||||
---
|
||||
|
||||
# Core API 参考
|
||||
|
||||
## 概述
|
||||
|
||||
GFramework.Core 是框架的核心模块,提供架构基础、依赖注入、事件系统等核心功能。
|
||||
|
||||
## 类
|
||||
|
||||
- [Architecture](./architecture.md) - 架构基类
|
||||
- [ArchitectureConfiguration](./architecture-configuration.md) - 架构配置
|
||||
- [IocContainer](./ioc-container.md) - IoC 容器
|
||||
|
||||
## 接口
|
||||
|
||||
- [IArchitecture](./iarchitecture.md) - 架构接口
|
||||
- [IModel](./imodel.md) - 模型接口
|
||||
- [ISystem](./isystem.md) - 系统接口
|
||||
|
||||
## 枚举
|
||||
|
||||
- [ArchitecturePhase](./architecture-phase.md) - 架构阶段
|
||||
```
|
||||
|
||||
### 目录结构
|
||||
|
||||
```
|
||||
docs/zh-CN/api-reference/
|
||||
├── core/
|
||||
│ ├── index.md # 模块索引
|
||||
│ ├── architecture.md
|
||||
│ ├── iarchitecture.md
|
||||
│ └── ...
|
||||
├── game/
|
||||
│ ├── index.md
|
||||
│ └── ...
|
||||
└── godot/
|
||||
├── index.md
|
||||
└── ...
|
||||
```
|
||||
|
||||
## 模块映射
|
||||
|
||||
### 源代码目录映射
|
||||
|
||||
| 模块名 | 源代码目录 | 输出目录 |
|
||||
|--------|-----------|---------|
|
||||
| Core | `GFramework.Core/` | `docs/zh-CN/api-reference/core/` |
|
||||
| Game | `GFramework.Game/` | `docs/zh-CN/api-reference/game/` |
|
||||
| Godot | `GFramework.Godot/` | `docs/zh-CN/api-reference/godot/` |
|
||||
| SourceGenerators | `GFramework.SourceGenerators/` | `docs/zh-CN/api-reference/source-generators/` |
|
||||
|
||||
### 命名空间映射
|
||||
|
||||
- `GFramework.Core.*` → Core 模块
|
||||
- `GFramework.Game.*` → Game 模块
|
||||
- `GFramework.Godot.*` → Godot 模块
|
||||
- `GFramework.SourceGenerators.*` → SourceGenerators 模块
|
||||
|
||||
## 过滤规则
|
||||
|
||||
### 包含的文件
|
||||
|
||||
- 公共类(public class)
|
||||
- 公共接口(public interface)
|
||||
- 公共枚举(public enum)
|
||||
- 公共结构体(public struct)
|
||||
|
||||
### 排除的文件
|
||||
|
||||
- 内部类型(internal)
|
||||
- 生成的代码(`*.g.cs`、`*.Designer.cs`)
|
||||
- 测试文件(`*.Tests.cs`、`*Test.cs`)
|
||||
- 临时文件(`*.tmp.cs`)
|
||||
- 编译器生成的文件(`AssemblyInfo.cs`)
|
||||
|
||||
### 排除的类型
|
||||
|
||||
- 编译器生成的类型(`<>c__DisplayClass`)
|
||||
- 匿名类型
|
||||
- 嵌套的私有类型
|
||||
|
||||
## 批量处理脚本
|
||||
|
||||
### batch-generate.sh
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# 批量生成 API 文档
|
||||
# 用法: batch-generate.sh <模块名>
|
||||
|
||||
set -e
|
||||
|
||||
MODULE="$1"
|
||||
|
||||
if [ -z "$MODULE" ]; then
|
||||
echo "用法: $0 <模块名>"
|
||||
echo "可用模块: Core, Game, Godot, SourceGenerators"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 确定源代码目录
|
||||
case "$MODULE" in
|
||||
Core)
|
||||
SOURCE_DIR="GFramework.Core"
|
||||
;;
|
||||
Game)
|
||||
SOURCE_DIR="GFramework.Game"
|
||||
;;
|
||||
Godot)
|
||||
SOURCE_DIR="GFramework.Godot"
|
||||
;;
|
||||
SourceGenerators)
|
||||
SOURCE_DIR="GFramework.SourceGenerators"
|
||||
;;
|
||||
*)
|
||||
echo "错误: 未知的模块: $MODULE"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ ! -d "$SOURCE_DIR" ]; then
|
||||
echo "错误: 源代码目录不存在: $SOURCE_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=========================================="
|
||||
echo "批量生成 $MODULE 模块的 API 文档"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# 查找所有 C# 文件
|
||||
FILES=$(find "$SOURCE_DIR" -name "*.cs" -type f \
|
||||
! -name "*.g.cs" \
|
||||
! -name "*.Designer.cs" \
|
||||
! -name "*Test.cs" \
|
||||
! -name "*.Tests.cs" \
|
||||
! -name "AssemblyInfo.cs")
|
||||
|
||||
FILE_COUNT=$(echo "$FILES" | wc -l)
|
||||
echo "找到 $FILE_COUNT 个文件"
|
||||
echo ""
|
||||
|
||||
GENERATED=0
|
||||
SKIPPED=0
|
||||
FAILED=0
|
||||
|
||||
for FILE in $FILES; do
|
||||
echo "处理: $FILE"
|
||||
|
||||
# 检查是否包含公共类型
|
||||
if ! grep -q "public \(class\|interface\|enum\|struct\)" "$FILE"; then
|
||||
echo " ⊘ 跳过(无公共类型)"
|
||||
SKIPPED=$((SKIPPED + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# 调用 vitepress-api-doc(由 AI 执行)
|
||||
# /vitepress-api-doc "$FILE"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo " ✓ 生成成功"
|
||||
GENERATED=$((GENERATED + 1))
|
||||
else
|
||||
echo " ✗ 生成失败"
|
||||
FAILED=$((FAILED + 1))
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "=========================================="
|
||||
echo "批量生成完成"
|
||||
echo "=========================================="
|
||||
echo "总文件数: $FILE_COUNT"
|
||||
echo "生成成功: $GENERATED"
|
||||
echo "跳过: $SKIPPED"
|
||||
echo "失败: $FAILED"
|
||||
echo ""
|
||||
|
||||
if [ $FAILED -eq 0 ]; then
|
||||
echo "✓ 所有文档生成成功"
|
||||
exit 0
|
||||
else
|
||||
echo "✗ 部分文档生成失败"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
## 配置选项
|
||||
|
||||
### 过滤选项
|
||||
|
||||
```bash
|
||||
# 包含内部类型
|
||||
/vitepress-batch-api Core --include-internal
|
||||
|
||||
# 包含生成的代码
|
||||
/vitepress-batch-api Core --include-generated
|
||||
|
||||
# 自定义过滤规则
|
||||
/vitepress-batch-api Core --exclude "*.Tests.cs" --exclude "*.g.cs"
|
||||
```
|
||||
|
||||
### 输出选项
|
||||
|
||||
```bash
|
||||
# 指定输出目录
|
||||
/vitepress-batch-api Core --output docs/zh-CN/api-reference/core/
|
||||
|
||||
# 覆盖现有文档
|
||||
/vitepress-batch-api Core --force
|
||||
|
||||
# 仅生成索引页
|
||||
/vitepress-batch-api Core --index-only
|
||||
```
|
||||
|
||||
### 并行处理
|
||||
|
||||
```bash
|
||||
# 并行生成(加快速度)
|
||||
/vitepress-batch-api Core --parallel 4
|
||||
```
|
||||
|
||||
## 进度显示
|
||||
|
||||
### 实时进度
|
||||
|
||||
```
|
||||
========================================
|
||||
批量生成 Core 模块的 API 文档
|
||||
========================================
|
||||
|
||||
找到 45 个文件
|
||||
|
||||
[1/45] 处理: GFramework.Core/architecture/Architecture.cs
|
||||
✓ 生成成功
|
||||
|
||||
[2/45] 处理: GFramework.Core/architecture/IArchitecture.cs
|
||||
✓ 生成成功
|
||||
|
||||
[3/45] 处理: GFramework.Core/command/Command.cs
|
||||
⊘ 跳过(无公共类型)
|
||||
|
||||
...
|
||||
|
||||
[45/45] 处理: GFramework.Core/utility/Utility.cs
|
||||
✓ 生成成功
|
||||
|
||||
========================================
|
||||
批量生成完成
|
||||
========================================
|
||||
总文件数: 45
|
||||
生成成功: 38
|
||||
跳过: 5
|
||||
失败: 2
|
||||
|
||||
✗ 部分文档生成失败
|
||||
|
||||
失败的文件:
|
||||
- GFramework.Core/internal/InternalClass.cs (缺少 XML 注释)
|
||||
- GFramework.Core/legacy/LegacyClass.cs (解析错误)
|
||||
```
|
||||
|
||||
## 前置条件
|
||||
|
||||
1. 模块源代码目录存在
|
||||
2. 源代码文件包含 XML 文档注释
|
||||
3. 有足够的磁盘空间存储生成的文档
|
||||
|
||||
## 相关 Skills
|
||||
|
||||
- `/vitepress-api-doc` - 单文件 API 文档生成
|
||||
- `/vitepress-validate` - 验证生成的文档
|
||||
- `/vitepress-guide` - 生成功能指南
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **首次生成**:使用批量生成快速创建所有文档
|
||||
2. **增量更新**:修改代码后使用单文件生成更新对应文档
|
||||
3. **定期验证**:批量生成后运行验证确保质量
|
||||
4. **版本控制**:将生成的文档提交到版本控制系统
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 问题:部分文件生成失败
|
||||
**解决方案**:检查失败文件的 XML 注释是否完整,手动修复后重新生成
|
||||
|
||||
### 问题:生成速度慢
|
||||
**解决方案**:使用 `--parallel` 选项启用并行处理
|
||||
|
||||
### 问题:生成的文档过多
|
||||
**解决方案**:使用过滤选项排除不需要的文件
|
||||
|
||||
## 版本历史
|
||||
|
||||
- v1.0.0 - 初始版本,支持批量 API 文档生成
|
||||
@ -1,81 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 批量生成 API 文档
|
||||
# 用法: batch-generate.sh <模块名>
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=../../_shared/module-config.sh
|
||||
source "$SCRIPT_DIR/../../_shared/module-config.sh"
|
||||
|
||||
MODULE="$1"
|
||||
|
||||
if [ -z "$MODULE" ]; then
|
||||
echo "用法: $0 <模块名>"
|
||||
echo "可用模块: $(get_all_modules)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 验证模块名
|
||||
if ! is_valid_module "$MODULE"; then
|
||||
echo "错误: 未知的模块: $MODULE"
|
||||
echo "可用模块: $(get_all_modules)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 获取源代码目录
|
||||
SOURCE_DIR=$(get_source_dir "$MODULE")
|
||||
|
||||
if [ ! -d "$SOURCE_DIR" ]; then
|
||||
echo "错误: 源代码目录不存在: $SOURCE_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=========================================="
|
||||
echo "批量生成 $MODULE 模块的 API 文档"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# 查找所有 C# 文件
|
||||
mapfile -t FILES < <(find "$SOURCE_DIR" -name "*.cs" -type f \
|
||||
! -name "*.g.cs" \
|
||||
! -name "*.Designer.cs" \
|
||||
! -name "*Test.cs" \
|
||||
! -name "*.Tests.cs" \
|
||||
! -name "AssemblyInfo.cs")
|
||||
|
||||
FILE_COUNT=${#FILES[@]}
|
||||
echo "找到 $FILE_COUNT 个文件"
|
||||
echo ""
|
||||
|
||||
GENERATED=0
|
||||
SKIPPED=0
|
||||
FAILED=0
|
||||
|
||||
for FILE in "${FILES[@]}"; do
|
||||
echo "处理: $FILE"
|
||||
|
||||
# 检查是否包含公共类型
|
||||
if ! grep -q "public \(class\|interface\|enum\|struct\)" "$FILE"; then
|
||||
echo " ⊘ 跳过(无公共类型)"
|
||||
SKIPPED=$((SKIPPED + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# 注意: 实际的文档生成由 AI 调用 /vitepress-api-doc 完成
|
||||
# 此脚本仅用于扫描和过滤文件
|
||||
|
||||
echo " → 待生成"
|
||||
GENERATED=$((GENERATED + 1))
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "=========================================="
|
||||
echo "扫描完成"
|
||||
echo "=========================================="
|
||||
echo "总文件数: $FILE_COUNT"
|
||||
echo "待生成: $GENERATED"
|
||||
echo "跳过: $SKIPPED"
|
||||
echo ""
|
||||
|
||||
exit 0
|
||||
@ -1,52 +0,0 @@
|
||||
---
|
||||
name: vitepress-doc-generator
|
||||
description: Generate standardized VitePress documentation from source code.
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Role
|
||||
|
||||
You are a technical documentation generator specialized in VitePress.
|
||||
|
||||
# Objective
|
||||
|
||||
Analyze the provided code context and generate a structured VitePress-compatible Markdown document.
|
||||
|
||||
# Output Requirements
|
||||
|
||||
1. Output MUST be valid Markdown only.
|
||||
2. Include frontmatter:
|
||||
|
||||
---
|
||||
title: <Module Name>
|
||||
outline: deep
|
||||
---
|
||||
|
||||
3. No explanations.
|
||||
4. No conversational text.
|
||||
5. No emoji.
|
||||
6. Use Chinese.
|
||||
7. Use structured headings.
|
||||
|
||||
# Required Structure
|
||||
|
||||
# 模块概述
|
||||
- 模块职责
|
||||
- 设计目标
|
||||
|
||||
# 核心类说明
|
||||
## 类名
|
||||
### 职责
|
||||
### 主要方法
|
||||
### 依赖关系
|
||||
|
||||
# 设计模式分析
|
||||
# 可扩展性说明
|
||||
# 使用示例(如适用)
|
||||
|
||||
# Self-Validation
|
||||
|
||||
Before returning output, verify:
|
||||
- Frontmatter exists
|
||||
- All required sections exist
|
||||
- No extra commentary text
|
||||
@ -1,256 +0,0 @@
|
||||
# VitePress 功能指南生成
|
||||
|
||||
生成功能模块的使用指南文档,包括概念说明、用法示例和最佳实践。
|
||||
|
||||
## 用途
|
||||
|
||||
此 skill 用于生成结构化的功能指南文档,适用于:
|
||||
- 核心功能模块的使用说明
|
||||
- 设计模式和架构概念
|
||||
- 系统功能的详细介绍
|
||||
- 最佳实践和常见问题
|
||||
|
||||
## 调用方式
|
||||
|
||||
```bash
|
||||
/vitepress-guide <主题> <目标模块>
|
||||
```
|
||||
|
||||
**示例**:
|
||||
```bash
|
||||
/vitepress-guide "事件系统" Core
|
||||
/vitepress-guide "IoC 容器" Core
|
||||
/vitepress-guide "Godot 节点扩展" Godot
|
||||
```
|
||||
|
||||
## 工作流程
|
||||
|
||||
1. **收集需求**
|
||||
- 询问用户指南主题
|
||||
- 确定目标受众(初学者/进阶/专家)
|
||||
- 了解重点内容(概念/用法/最佳实践)
|
||||
|
||||
2. **搜索相关资源**
|
||||
- 搜索相关代码文件
|
||||
- 查找现有文档
|
||||
- 识别相关类型和接口
|
||||
|
||||
3. **生成指南结构**
|
||||
- 根据 `template.md` 创建文档框架
|
||||
- 填充概述和核心概念
|
||||
- 添加基本用法和高级用法
|
||||
- 补充最佳实践和常见问题
|
||||
|
||||
4. **生成代码示例**
|
||||
- 基本用法示例(最简单的场景)
|
||||
- 常见场景示例(实际应用)
|
||||
- 高级用法示例(复杂配置)
|
||||
|
||||
5. **确定输出路径**
|
||||
- 保存到 `docs/zh-CN/<模块>/`
|
||||
- 文件名使用小写加连字符(如 `event-system.md`)
|
||||
|
||||
6. **更新导航配置**
|
||||
- 在 VitePress 侧边栏中添加新指南
|
||||
|
||||
## 输出规范
|
||||
|
||||
### Frontmatter 格式
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: 指南标题
|
||||
description: 简短描述(1-2 句话)
|
||||
---
|
||||
```
|
||||
|
||||
### 文档结构
|
||||
|
||||
1. **概述**:功能的简介和用途
|
||||
2. **核心概念**:关键概念和术语解释
|
||||
3. **基本用法**:最简单的使用方式
|
||||
4. **高级用法**:复杂场景和配置
|
||||
5. **最佳实践**:推荐的使用方式
|
||||
6. **常见问题**:FAQ 和故障排除
|
||||
|
||||
### 章节示例
|
||||
|
||||
**概述**:
|
||||
```markdown
|
||||
## 概述
|
||||
|
||||
事件系统提供了一种松耦合的组件间通信机制。通过事件,不同的组件可以在不直接引用彼此的情况下进行交互。
|
||||
|
||||
**主要特性**:
|
||||
- 类型安全的事件
|
||||
- 自动内存管理
|
||||
- 支持事件优先级
|
||||
- 线程安全
|
||||
```
|
||||
|
||||
**核心概念**:
|
||||
```markdown
|
||||
## 核心概念
|
||||
|
||||
### 事件类型
|
||||
|
||||
事件是一个普通的 C# 类,用于携带事件数据:
|
||||
|
||||
\`\`\`csharp
|
||||
public class PlayerDiedEvent
|
||||
{
|
||||
public int PlayerId { get; set; }
|
||||
public string Reason { get; set; }
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
### 事件发送
|
||||
|
||||
通过架构发送事件:
|
||||
|
||||
\`\`\`csharp
|
||||
this.SendEvent(new PlayerDiedEvent
|
||||
{
|
||||
PlayerId = 1,
|
||||
Reason = "Fall damage"
|
||||
});
|
||||
\`\`\`
|
||||
|
||||
### 事件监听
|
||||
|
||||
注册事件监听器:
|
||||
|
||||
\`\`\`csharp
|
||||
this.RegisterEvent<PlayerDiedEvent>(OnPlayerDied);
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
## 模板变量
|
||||
|
||||
- `{{GUIDE_TITLE}}` - 指南标题
|
||||
- `{{GUIDE_DESCRIPTION}}` - 简短描述
|
||||
- `{{OVERVIEW}}` - 概述内容
|
||||
- `{{CORE_CONCEPTS}}` - 核心概念
|
||||
- `{{BASIC_USAGE}}` - 基本用法
|
||||
- `{{ADVANCED_USAGE}}` - 高级用法
|
||||
- `{{BEST_PRACTICES}}` - 最佳实践
|
||||
- `{{FAQ}}` - 常见问题
|
||||
|
||||
## 示例输出
|
||||
|
||||
参考 `examples/guide-example.md`,该示例基于现有的 IoC 容器文档创建。
|
||||
|
||||
## 内容要求
|
||||
|
||||
### 概述部分
|
||||
- 1-2 段简介
|
||||
- 列出主要特性(3-5 个)
|
||||
- 说明适用场景
|
||||
|
||||
### 核心概念部分
|
||||
- 使用三级标题(###)分隔不同概念
|
||||
- 每个概念包含简短说明和代码示例
|
||||
- 解释关键术语
|
||||
|
||||
### 基本用法部分
|
||||
- 提供完整的可运行示例
|
||||
- 从最简单的场景开始
|
||||
- 逐步增加复杂度
|
||||
- 包含必要的 using 语句
|
||||
|
||||
### 高级用法部分
|
||||
- 展示复杂场景
|
||||
- 说明配置选项
|
||||
- 提供性能优化建议
|
||||
|
||||
### 最佳实践部分
|
||||
- 使用编号列表
|
||||
- 每条实践包含简短说明
|
||||
- 提供正反示例(✓ 推荐 / ✗ 不推荐)
|
||||
|
||||
### 常见问题部分
|
||||
- 使用问答格式
|
||||
- 提供具体的解决方案
|
||||
- 包含相关链接
|
||||
|
||||
## 写作风格
|
||||
|
||||
### 语气
|
||||
- 友好、专业
|
||||
- 使用第二人称("你")
|
||||
- 避免过于技术化的术语
|
||||
|
||||
### 代码示例
|
||||
- 完整且可运行
|
||||
- 包含注释说明关键步骤
|
||||
- 使用有意义的变量名
|
||||
- 遵循项目代码风格
|
||||
|
||||
### 格式
|
||||
- 使用 Markdown 标准格式
|
||||
- 代码块使用语法高亮
|
||||
- 重要内容使用粗体或引用块
|
||||
- 适当使用列表和表格
|
||||
|
||||
## 配置选项
|
||||
|
||||
### 目标受众
|
||||
|
||||
```bash
|
||||
# 初学者(更多解释,简单示例)
|
||||
/vitepress-guide "事件系统" Core --audience beginner
|
||||
|
||||
# 进阶(平衡解释和示例)
|
||||
/vitepress-guide "事件系统" Core --audience intermediate
|
||||
|
||||
# 专家(简洁说明,复杂示例)
|
||||
/vitepress-guide "事件系统" Core --audience expert
|
||||
```
|
||||
|
||||
### 重点内容
|
||||
|
||||
```bash
|
||||
# 侧重概念
|
||||
/vitepress-guide "事件系统" Core --focus concepts
|
||||
|
||||
# 侧重用法
|
||||
/vitepress-guide "事件系统" Core --focus usage
|
||||
|
||||
# 侧重最佳实践
|
||||
/vitepress-guide "事件系统" Core --focus best-practices
|
||||
```
|
||||
|
||||
## 前置条件
|
||||
|
||||
1. 了解指南主题的基本概念
|
||||
2. 能够访问相关代码文件
|
||||
3. 了解项目的代码风格和术语
|
||||
|
||||
## 相关 Skills
|
||||
|
||||
- `/vitepress-api-doc` - 生成 API 参考文档
|
||||
- `/vitepress-tutorial` - 生成分步教程
|
||||
- `/vitepress-validate` - 验证生成的文档
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **先搜索后编写**:查看现有文档和代码,保持一致性
|
||||
2. **使用真实示例**:基于项目实际代码创建示例
|
||||
3. **保持简洁**:每个章节聚焦一个主题
|
||||
4. **提供完整代码**:确保示例可以直接运行
|
||||
5. **添加交叉引用**:链接到相关的 API 文档和其他指南
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 问题:不确定指南应该包含哪些内容
|
||||
**解决方案**:参考 `examples/guide-example.md` 和现有的指南文档
|
||||
|
||||
### 问题:代码示例过于复杂
|
||||
**解决方案**:将复杂示例拆分为多个简单示例,逐步增加复杂度
|
||||
|
||||
### 问题:概念解释不清晰
|
||||
**解决方案**:使用类比、图表或分步说明来辅助解释
|
||||
|
||||
## 版本历史
|
||||
|
||||
- v1.0.0 - 初始版本,支持功能指南生成
|
||||
@ -1,283 +0,0 @@
|
||||
---
|
||||
title: IoC 容器使用指南
|
||||
description: IoC(控制反转)容器提供了轻量级的依赖注入功能,用于管理框架中各种组件的注册和获取。
|
||||
---
|
||||
|
||||
# IoC 容器使用指南
|
||||
|
||||
## 概述
|
||||
|
||||
IoC(Inversion of Control,控制反转)包提供了一个轻量级的依赖注入容器,用于管理框架中各种组件的注册和获取。通过 IoC 容器,可以实现组件间的解耦,便于测试和维护。
|
||||
|
||||
IoC 容器是 GFramework 架构的核心组件之一,为整个框架提供依赖管理和组件解析服务。
|
||||
|
||||
**主要特性**:
|
||||
- 类型安全的依赖管理
|
||||
- 支持单例和多实例注册
|
||||
- 线程安全操作
|
||||
- 容器冻结保护
|
||||
- 自动接口注册
|
||||
|
||||
## 核心概念
|
||||
|
||||
### 依赖注入
|
||||
|
||||
依赖注入是一种设计模式,通过容器管理对象的创建和依赖关系,而不是在代码中直接创建对象。
|
||||
|
||||
```csharp
|
||||
// 不使用依赖注入
|
||||
public class GameController
|
||||
{
|
||||
private PlayerModel model = new PlayerModel(); // 硬编码依赖
|
||||
}
|
||||
|
||||
// 使用依赖注入
|
||||
public class GameController : IController
|
||||
{
|
||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
var model = this.GetModel<PlayerModel>(); // 从容器获取
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 容器注册
|
||||
|
||||
在架构初始化时,将组件注册到容器中:
|
||||
|
||||
```csharp
|
||||
public class GameArchitecture : Architecture
|
||||
{
|
||||
protected override void Init()
|
||||
{
|
||||
// 注册 Model
|
||||
RegisterModel(new PlayerModel());
|
||||
|
||||
// 注册 System
|
||||
RegisterSystem(new GameplaySystem());
|
||||
|
||||
// 注册 Utility
|
||||
RegisterUtility(new StorageUtility());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 容器解析
|
||||
|
||||
通过扩展方法从容器中获取已注册的组件:
|
||||
|
||||
```csharp
|
||||
// 在 Controller 中
|
||||
var playerModel = this.GetModel<PlayerModel>();
|
||||
var gameplaySystem = this.GetSystem<GameplaySystem>();
|
||||
var storageUtility = this.GetUtility<StorageUtility>();
|
||||
```
|
||||
|
||||
## 基本用法
|
||||
|
||||
### 注册组件
|
||||
|
||||
```csharp
|
||||
var container = new IocContainer();
|
||||
|
||||
// 注册单例(一个类型只能有一个实例)
|
||||
container.RegisterSingleton<IPlayerModel>(new PlayerModel());
|
||||
|
||||
// 注册多实例(一个类型可以有多个实例)
|
||||
container.RegisterPlurality<IEnemy>(new Goblin());
|
||||
container.RegisterPlurality<IEnemy>(new Orc());
|
||||
container.RegisterPlurality<IEnemy>(new Dragon());
|
||||
```
|
||||
|
||||
### 获取组件
|
||||
|
||||
```csharp
|
||||
// 获取单例
|
||||
var playerModel = container.Get<IPlayerModel>();
|
||||
|
||||
// 获取多实例集合
|
||||
var enemies = container.GetAll<IEnemy>(); // 返回 List<IEnemy>
|
||||
```
|
||||
|
||||
### 在架构中使用
|
||||
|
||||
```csharp
|
||||
public class GameArchitecture : Architecture
|
||||
{
|
||||
protected override void Init()
|
||||
{
|
||||
// 注册组件
|
||||
RegisterModel(new PlayerModel());
|
||||
RegisterModel(new InventoryModel());
|
||||
RegisterSystem(new GameplaySystem());
|
||||
}
|
||||
}
|
||||
|
||||
// 在 Controller 中使用
|
||||
public class GameController : IController
|
||||
{
|
||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
// 通过扩展方法获取组件
|
||||
var playerModel = this.GetModel<PlayerModel>();
|
||||
var inventoryModel = this.GetModel<InventoryModel>();
|
||||
var gameplaySystem = this.GetSystem<GameplaySystem>();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 高级用法
|
||||
|
||||
### 容器冻结
|
||||
|
||||
容器在架构初始化完成后会被冻结,防止运行时修改:
|
||||
|
||||
```csharp
|
||||
var container = new IocContainer();
|
||||
container.Register<IPlayerModel>(new PlayerModel());
|
||||
|
||||
// 冻结容器
|
||||
container.Freeze();
|
||||
|
||||
// 以下操作会抛出 InvalidOperationException
|
||||
// container.Register<IGameSystem>(new GameSystem());
|
||||
```
|
||||
|
||||
### 多实例管理
|
||||
|
||||
```csharp
|
||||
// 注册多个同类型实例
|
||||
container.RegisterPlurality<IWeapon>(new Sword());
|
||||
container.RegisterPlurality<IWeapon>(new Bow());
|
||||
container.RegisterPlurality<IWeapon>(new Staff());
|
||||
|
||||
// 获取所有实例
|
||||
var allWeapons = container.GetAll<IWeapon>();
|
||||
foreach (var weapon in allWeapons)
|
||||
{
|
||||
weapon.Attack();
|
||||
}
|
||||
```
|
||||
|
||||
### 接口自动注册
|
||||
|
||||
注册实例时,容器会自动将其注册到所有实现的接口:
|
||||
|
||||
```csharp
|
||||
public class PlayerModel : IModel, IPlayerModel, IDisposable
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// 注册实例
|
||||
container.Register<PlayerModel>(new PlayerModel());
|
||||
|
||||
// 可以通过任何接口获取
|
||||
var model1 = container.Get<IModel>();
|
||||
var model2 = container.Get<IPlayerModel>();
|
||||
var model3 = container.Get<IDisposable>();
|
||||
// 以上三个变量指向同一个实例
|
||||
```
|
||||
|
||||
### 线程安全操作
|
||||
|
||||
容器的所有操作都是线程安全的:
|
||||
|
||||
```csharp
|
||||
// 多线程环境下安全使用
|
||||
Parallel.For(0, 100, i =>
|
||||
{
|
||||
var model = container.Get<IPlayerModel>();
|
||||
model.DoSomething();
|
||||
});
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **使用接口注册**:优先使用接口类型注册,而不是具体类型
|
||||
```csharp
|
||||
✓ container.Register<IPlayerModel>(new PlayerModel());
|
||||
✗ container.Register<PlayerModel>(new PlayerModel());
|
||||
```
|
||||
|
||||
2. **单例 vs 多实例**:根据需求选择合适的注册方式
|
||||
- 单例:全局唯一的服务(如配置、管理器)
|
||||
- 多实例:可以有多个实例的对象(如敌人、道具)
|
||||
|
||||
3. **避免循环依赖**:组件之间不应该相互依赖
|
||||
```csharp
|
||||
✗ System A 依赖 System B,System B 又依赖 System A
|
||||
✓ 使用事件系统进行通信,避免直接依赖
|
||||
```
|
||||
|
||||
4. **在 Init 中注册**:所有组件应该在架构的 `Init()` 方法中注册
|
||||
```csharp
|
||||
protected override void Init()
|
||||
{
|
||||
// 在这里注册所有组件
|
||||
RegisterModel(new PlayerModel());
|
||||
RegisterSystem(new GameplaySystem());
|
||||
}
|
||||
```
|
||||
|
||||
5. **使用扩展方法**:通过扩展方法获取组件,代码更简洁
|
||||
```csharp
|
||||
✓ var model = this.GetModel<PlayerModel>();
|
||||
✗ var model = this.GetArchitecture().GetModel<PlayerModel>();
|
||||
```
|
||||
|
||||
6. **不要在运行时注册**:容器冻结后不应该再注册新组件
|
||||
```csharp
|
||||
✗ 在游戏运行时动态注册组件
|
||||
✓ 在架构初始化时注册所有需要的组件
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 问题:如何判断使用单例还是多实例?
|
||||
|
||||
**解答**:
|
||||
- 使用单例(`RegisterSingleton`):全局唯一的服务,如 PlayerModel、GameConfiguration
|
||||
- 使用多实例(`RegisterPlurality`):可以有多个实例的对象,如 Enemy、Weapon
|
||||
|
||||
### 问题:容器冻结后如何添加新组件?
|
||||
|
||||
**解答**:
|
||||
容器冻结是为了保护架构稳定性。如果需要动态添加组件,应该:
|
||||
1. 在架构初始化时预先注册所有可能需要的组件
|
||||
2. 使用对象池模式管理动态对象
|
||||
3. 考虑使用工厂模式创建临时对象
|
||||
|
||||
### 问题:如何处理组件的生命周期?
|
||||
|
||||
**解答**:
|
||||
- 实现 `IDisposable` 接口的组件会在架构销毁时自动释放
|
||||
- 架构会按注册的逆序销毁组件
|
||||
- 不需要手动管理组件的生命周期
|
||||
|
||||
### 问题:可以在容器中注册值类型吗?
|
||||
|
||||
**解答**:
|
||||
可以,但会发生装箱。建议将值类型包装在类中:
|
||||
```csharp
|
||||
// 不推荐
|
||||
container.Register<int>(42);
|
||||
|
||||
// 推荐
|
||||
public class GameConfig
|
||||
{
|
||||
public int MaxPlayers { get; set; } = 42;
|
||||
}
|
||||
container.Register<GameConfig>(new GameConfig());
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [架构组件](/zh-CN/core/architecture) - 架构基础
|
||||
- [Model 层](/zh-CN/core/model) - 数据模型
|
||||
- [System 层](/zh-CN/core/system) - 业务系统
|
||||
- [Utility 工具类](/zh-CN/core/utility) - 工具类
|
||||
@ -1,34 +0,0 @@
|
||||
---
|
||||
title: {{GUIDE_TITLE}}
|
||||
description: {{GUIDE_DESCRIPTION}}
|
||||
---
|
||||
|
||||
# {{GUIDE_TITLE}}
|
||||
|
||||
## 概述
|
||||
|
||||
{{OVERVIEW}}
|
||||
|
||||
## 核心概念
|
||||
|
||||
{{CORE_CONCEPTS}}
|
||||
|
||||
## 基本用法
|
||||
|
||||
{{BASIC_USAGE}}
|
||||
|
||||
## 高级用法
|
||||
|
||||
{{ADVANCED_USAGE}}
|
||||
|
||||
## 最佳实践
|
||||
|
||||
{{BEST_PRACTICES}}
|
||||
|
||||
## 常见问题
|
||||
|
||||
{{FAQ}}
|
||||
|
||||
## 相关文档
|
||||
|
||||
{{RELATED_DOCS}}
|
||||
@ -1,253 +0,0 @@
|
||||
# VitePress 教程生成
|
||||
|
||||
生成分步教程文档,适合初学者学习框架功能。
|
||||
|
||||
## 用途
|
||||
|
||||
此 skill 用于生成结构化的分步教程,适用于:
|
||||
- 框架入门教程
|
||||
- 功能实现教程
|
||||
- 最佳实践演示
|
||||
- 问题解决方案
|
||||
|
||||
## 调用方式
|
||||
|
||||
```bash
|
||||
/vitepress-tutorial <教程主题>
|
||||
```
|
||||
|
||||
**示例**:
|
||||
```bash
|
||||
/vitepress-tutorial "创建第一个 System"
|
||||
/vitepress-tutorial "实现自定义命令"
|
||||
/vitepress-tutorial "使用事件系统"
|
||||
```
|
||||
|
||||
## 工作流程
|
||||
|
||||
1. **收集需求**
|
||||
- 询问用户教程主题
|
||||
- 确定学习目标
|
||||
- 了解前置知识要求
|
||||
|
||||
2. **设计教程步骤**
|
||||
- 将任务分解为 3-7 个步骤
|
||||
- 每步聚焦一个具体任务
|
||||
- 确保步骤之间逻辑连贯
|
||||
|
||||
3. **生成教程内容**
|
||||
- 根据 `template.md` 创建文档框架
|
||||
- 为每步编写详细说明和代码
|
||||
- 添加完整的可运行代码
|
||||
- 说明预期结果
|
||||
|
||||
4. **确定输出路径**
|
||||
- 保存到 `docs/zh-CN/tutorials/`
|
||||
- 文件名使用小写加连字符
|
||||
|
||||
5. **更新导航配置**
|
||||
- 在 VitePress 侧边栏中添加新教程
|
||||
|
||||
## 输出规范
|
||||
|
||||
### Frontmatter 格式
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: 教程标题
|
||||
description: 简短描述(1 句话说明学习内容)
|
||||
---
|
||||
```
|
||||
|
||||
### 文档结构
|
||||
|
||||
1. **学习目标**:完成教程后能够掌握的技能
|
||||
2. **前置条件**:需要的前置知识和环境
|
||||
3. **步骤 1-N**:分步说明(3-7 步)
|
||||
4. **完整代码**:汇总所有代码
|
||||
5. **运行结果**:预期输出和效果
|
||||
6. **下一步**:后续学习建议
|
||||
|
||||
### 步骤格式
|
||||
|
||||
每个步骤应包含:
|
||||
- 步骤标题(简短、动词开头)
|
||||
- 步骤说明(为什么要这样做)
|
||||
- 代码示例(完整且可运行)
|
||||
- 代码解释(关键部分的说明)
|
||||
|
||||
**示例**:
|
||||
```markdown
|
||||
## 步骤 1:创建 Model 类
|
||||
|
||||
首先,我们需要创建一个 Model 来存储玩家数据。Model 负责管理应用的数据和状态。
|
||||
|
||||
\`\`\`csharp
|
||||
using GFramework.Core.Abstractions.model;
|
||||
using GFramework.Core.Abstractions.property;
|
||||
|
||||
public class PlayerModel : IModel
|
||||
{
|
||||
// 玩家名称(可绑定属性)
|
||||
public BindableProperty<string> Name { get; } = new("Player");
|
||||
|
||||
// 玩家生命值
|
||||
public BindableProperty<int> Health { get; } = new(100);
|
||||
|
||||
// 玩家金币
|
||||
public BindableProperty<int> Gold { get; } = new(0);
|
||||
|
||||
public void Init() { }
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**代码说明**:
|
||||
- `BindableProperty<T>` 是可绑定属性,值变化时会自动通知监听者
|
||||
- `Init()` 方法在 Model 注册到架构时被调用
|
||||
- 使用属性初始化器设置默认值
|
||||
```
|
||||
|
||||
## 模板变量
|
||||
|
||||
- `{{TUTORIAL_TITLE}}` - 教程标题
|
||||
- `{{TUTORIAL_DESCRIPTION}}` - 简短描述
|
||||
- `{{LEARNING_OBJECTIVES}}` - 学习目标
|
||||
- `{{PREREQUISITES}}` - 前置条件
|
||||
- `{{STEP_N_TITLE}}` - 步骤标题
|
||||
- `{{STEP_N_CONTENT}}` - 步骤内容
|
||||
- `{{FULL_CODE}}` - 完整代码
|
||||
- `{{EXPECTED_OUTPUT}}` - 预期输出
|
||||
- `{{NEXT_STEPS}}` - 下一步建议
|
||||
|
||||
## 示例输出
|
||||
|
||||
参考 `examples/tutorial-example.md`,该示例基于现有的教程文档创建。
|
||||
|
||||
## 内容要求
|
||||
|
||||
### 学习目标
|
||||
- 使用列表格式
|
||||
- 3-5 个具体的学习目标
|
||||
- 使用"能够..."句式
|
||||
|
||||
**示例**:
|
||||
```markdown
|
||||
## 学习目标
|
||||
|
||||
完成本教程后,你将能够:
|
||||
- 创建自定义的 Model 类
|
||||
- 在架构中注册 Model
|
||||
- 从 Controller 中访问 Model
|
||||
- 使用可绑定属性管理数据
|
||||
```
|
||||
|
||||
### 前置条件
|
||||
- 列出必需的知识
|
||||
- 说明环境要求
|
||||
- 提供相关文档链接
|
||||
|
||||
**示例**:
|
||||
```markdown
|
||||
## 前置条件
|
||||
|
||||
- 已安装 GFramework.Core NuGet 包
|
||||
- 了解 C# 基础语法
|
||||
- 阅读过[架构概览](/zh-CN/getting-started)
|
||||
```
|
||||
|
||||
### 步骤内容
|
||||
- 每步 100-300 字说明
|
||||
- 包含完整的代码示例
|
||||
- 解释关键代码的作用
|
||||
- 使用注释标注重要部分
|
||||
|
||||
### 完整代码
|
||||
- 汇总所有步骤的代码
|
||||
- 确保可以直接复制运行
|
||||
- 包含必要的 using 语句
|
||||
- 添加文件结构说明
|
||||
|
||||
### 运行结果
|
||||
- 描述预期的输出
|
||||
- 如果有界面,提供截图或描述
|
||||
- 说明如何验证结果正确
|
||||
|
||||
### 下一步
|
||||
- 推荐 2-3 个后续教程
|
||||
- 提供相关文档链接
|
||||
- 建议进阶学习方向
|
||||
|
||||
## 写作风格
|
||||
|
||||
### 语气
|
||||
- 友好、鼓励性
|
||||
- 使用第二人称("你")
|
||||
- 避免假设读者已有高级知识
|
||||
|
||||
### 步骤说明
|
||||
- 使用主动语态
|
||||
- 步骤标题使用动词开头
|
||||
- 说明"为什么"而不仅是"怎么做"
|
||||
|
||||
### 代码示例
|
||||
- 完整且可运行
|
||||
- 包含详细注释
|
||||
- 使用有意义的变量名
|
||||
- 遵循项目代码风格
|
||||
|
||||
## 配置选项
|
||||
|
||||
### 教程难度
|
||||
|
||||
```bash
|
||||
# 初学者(更多解释,简单示例)
|
||||
/vitepress-tutorial "创建第一个 System" --level beginner
|
||||
|
||||
# 中级(平衡解释和复杂度)
|
||||
/vitepress-tutorial "实现自定义命令" --level intermediate
|
||||
|
||||
# 高级(简洁说明,复杂示例)
|
||||
/vitepress-tutorial "架构模块开发" --level advanced
|
||||
```
|
||||
|
||||
### 步骤数量
|
||||
|
||||
```bash
|
||||
# 指定步骤数量(3-7 步)
|
||||
/vitepress-tutorial "使用事件系统" --steps 5
|
||||
```
|
||||
|
||||
## 前置条件
|
||||
|
||||
1. 了解教程主题的基本概念
|
||||
2. 能够访问相关代码文件
|
||||
3. 了解目标受众的知识水平
|
||||
|
||||
## 相关 Skills
|
||||
|
||||
- `/vitepress-api-doc` - 生成 API 参考文档
|
||||
- `/vitepress-guide` - 生成功能指南
|
||||
- `/vitepress-validate` - 验证生成的文档
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **从简单开始**:第一步应该是最简单的操作
|
||||
2. **逐步增加复杂度**:每步在前一步基础上增加新内容
|
||||
3. **提供完整代码**:确保每步的代码都可以运行
|
||||
4. **解释关键概念**:不要假设读者已经了解所有术语
|
||||
5. **测试教程**:确保按照步骤操作能够得到预期结果
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 问题:步骤过多,教程太长
|
||||
**解决方案**:将教程拆分为多个小教程,或合并相似的步骤
|
||||
|
||||
### 问题:代码示例不完整
|
||||
**解决方案**:在"完整代码"章节提供所有文件的完整代码
|
||||
|
||||
### 问题:读者反馈步骤不清晰
|
||||
**解决方案**:增加更多说明,使用截图或图表辅助
|
||||
|
||||
## 版本历史
|
||||
|
||||
- v1.0.0 - 初始版本,支持分步教程生成
|
||||
@ -1,347 +0,0 @@
|
||||
---
|
||||
title: 创建第一个 Model
|
||||
description: 学习如何创建和使用 Model 来管理应用数据
|
||||
---
|
||||
|
||||
# 创建第一个 Model
|
||||
|
||||
## 学习目标
|
||||
|
||||
完成本教程后,你将能够:
|
||||
- 理解 Model 在架构中的作用
|
||||
- 创建自定义的 Model 类
|
||||
- 在架构中注册 Model
|
||||
- 从 Controller 中访问 Model
|
||||
- 使用可绑定属性管理数据
|
||||
|
||||
## 前置条件
|
||||
|
||||
- 已安装 GFramework.Core NuGet 包
|
||||
- 了解 C# 基础语法
|
||||
- 阅读过[架构概览](/zh-CN/getting-started)
|
||||
|
||||
## 步骤 1:创建 Model 类
|
||||
|
||||
首先,我们需要创建一个 Model 来存储玩家数据。Model 负责管理应用的数据和状态。
|
||||
|
||||
```csharp
|
||||
using GFramework.Core.Abstractions.model;
|
||||
using GFramework.Core.Abstractions.property;
|
||||
|
||||
namespace MyGame.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 玩家数据模型
|
||||
/// </summary>
|
||||
public class PlayerModel : IModel
|
||||
{
|
||||
// 玩家名称(可绑定属性)
|
||||
public BindableProperty<string> Name { get; } = new("Player");
|
||||
|
||||
// 玩家生命值
|
||||
public BindableProperty<int> Health { get; } = new(100);
|
||||
|
||||
// 玩家金币
|
||||
public BindableProperty<int> Gold { get; } = new(0);
|
||||
|
||||
// 玩家等级
|
||||
public BindableProperty<int> Level { get; } = new(1);
|
||||
|
||||
/// <summary>
|
||||
/// Model 初始化方法
|
||||
/// </summary>
|
||||
public void Init()
|
||||
{
|
||||
// 在这里可以进行初始化操作
|
||||
// 例如:从配置文件加载默认值
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**代码说明**:
|
||||
- `IModel` 接口标识这是一个数据模型
|
||||
- `BindableProperty<T>` 是可绑定属性,值变化时会自动通知监听者
|
||||
- `Init()` 方法在 Model 注册到架构时被调用
|
||||
- 使用属性初始化器设置默认值
|
||||
|
||||
## 步骤 2:在架构中注册 Model
|
||||
|
||||
创建架构类并注册 Model:
|
||||
|
||||
```csharp
|
||||
using GFramework.Core.architecture;
|
||||
using MyGame.Models;
|
||||
|
||||
namespace MyGame
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏架构
|
||||
/// </summary>
|
||||
public class GameArchitecture : Architecture
|
||||
{
|
||||
// 单例访问点
|
||||
public static IArchitecture Interface { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始化架构
|
||||
/// </summary>
|
||||
protected override void Init()
|
||||
{
|
||||
Interface = this;
|
||||
|
||||
// 注册 Model
|
||||
RegisterModel(new PlayerModel());
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**代码说明**:
|
||||
- 继承 `Architecture` 基类
|
||||
- 在 `Init()` 方法中注册 Model
|
||||
- 提供静态属性 `Interface` 用于全局访问架构
|
||||
|
||||
## 步骤 3:创建 Controller 访问 Model
|
||||
|
||||
创建 Controller 来使用 Model:
|
||||
|
||||
```csharp
|
||||
using GFramework.Core.Abstractions.architecture;
|
||||
using GFramework.Core.Abstractions.controller;
|
||||
using GFramework.Core.extensions;
|
||||
using MyGame.Models;
|
||||
|
||||
namespace MyGame.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏控制器
|
||||
/// </summary>
|
||||
public class GameController : IController
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取架构实例
|
||||
/// </summary>
|
||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化玩家数据
|
||||
/// </summary>
|
||||
public void InitializePlayer()
|
||||
{
|
||||
// 获取 PlayerModel
|
||||
var playerModel = this.GetModel<PlayerModel>();
|
||||
|
||||
// 设置玩家数据
|
||||
playerModel.Name.Value = "勇者";
|
||||
playerModel.Health.Value = 100;
|
||||
playerModel.Gold.Value = 50;
|
||||
playerModel.Level.Value = 1;
|
||||
|
||||
// 监听属性变化
|
||||
playerModel.Health.RegisterOnValueChanged(health =>
|
||||
{
|
||||
Console.WriteLine($"玩家生命值变化: {health}");
|
||||
|
||||
if (health <= 0)
|
||||
{
|
||||
Console.WriteLine("玩家死亡!");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 玩家受到伤害
|
||||
/// </summary>
|
||||
public void TakeDamage(int damage)
|
||||
{
|
||||
var playerModel = this.GetModel<PlayerModel>();
|
||||
playerModel.Health.Value -= damage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 玩家获得金币
|
||||
/// </summary>
|
||||
public void AddGold(int amount)
|
||||
{
|
||||
var playerModel = this.GetModel<PlayerModel>();
|
||||
playerModel.Gold.Value += amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**代码说明**:
|
||||
- 实现 `IController` 接口
|
||||
- 通过 `this.GetModel<T>()` 扩展方法获取 Model
|
||||
- 使用 `.Value` 访问和修改属性值
|
||||
- 使用 `RegisterOnValueChanged` 监听属性变化
|
||||
|
||||
## 步骤 4:初始化并使用架构
|
||||
|
||||
在程序入口点初始化架构:
|
||||
|
||||
```csharp
|
||||
using MyGame;
|
||||
using MyGame.Controllers;
|
||||
|
||||
// 1. 创建并初始化架构
|
||||
var architecture = new GameArchitecture();
|
||||
architecture.Initialize();
|
||||
|
||||
// 2. 等待架构就绪
|
||||
await architecture.WaitUntilReadyAsync();
|
||||
|
||||
// 3. 创建 Controller 并使用
|
||||
var gameController = new GameController();
|
||||
|
||||
// 初始化玩家
|
||||
gameController.InitializePlayer();
|
||||
|
||||
// 玩家受到伤害
|
||||
gameController.TakeDamage(20);
|
||||
// 输出: 玩家生命值变化: 80
|
||||
|
||||
// 玩家获得金币
|
||||
gameController.AddGold(100);
|
||||
```
|
||||
|
||||
**代码说明**:
|
||||
- 创建架构实例并调用 `Initialize()`
|
||||
- 使用 `WaitUntilReadyAsync()` 等待架构就绪
|
||||
- 创建 Controller 实例并调用方法
|
||||
|
||||
## 完整代码
|
||||
|
||||
### PlayerModel.cs
|
||||
|
||||
```csharp
|
||||
using GFramework.Core.Abstractions.model;
|
||||
using GFramework.Core.Abstractions.property;
|
||||
|
||||
namespace MyGame.Models
|
||||
{
|
||||
public class PlayerModel : IModel
|
||||
{
|
||||
public BindableProperty<string> Name { get; } = new("Player");
|
||||
public BindableProperty<int> Health { get; } = new(100);
|
||||
public BindableProperty<int> Gold { get; } = new(0);
|
||||
public BindableProperty<int> Level { get; } = new(1);
|
||||
|
||||
public void Init() { }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### GameArchitecture.cs
|
||||
|
||||
```csharp
|
||||
using GFramework.Core.architecture;
|
||||
using MyGame.Models;
|
||||
|
||||
namespace MyGame
|
||||
{
|
||||
public class GameArchitecture : Architecture
|
||||
{
|
||||
public static IArchitecture Interface { get; private set; }
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
Interface = this;
|
||||
RegisterModel(new PlayerModel());
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### GameController.cs
|
||||
|
||||
```csharp
|
||||
using GFramework.Core.Abstractions.architecture;
|
||||
using GFramework.Core.Abstractions.controller;
|
||||
using GFramework.Core.extensions;
|
||||
using MyGame.Models;
|
||||
|
||||
namespace MyGame.Controllers
|
||||
{
|
||||
public class GameController : IController
|
||||
{
|
||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
||||
|
||||
public void InitializePlayer()
|
||||
{
|
||||
var playerModel = this.GetModel<PlayerModel>();
|
||||
playerModel.Name.Value = "勇者";
|
||||
playerModel.Health.Value = 100;
|
||||
playerModel.Gold.Value = 50;
|
||||
playerModel.Level.Value = 1;
|
||||
|
||||
playerModel.Health.RegisterOnValueChanged(health =>
|
||||
{
|
||||
Console.WriteLine($"玩家生命值变化: {health}");
|
||||
if (health <= 0)
|
||||
{
|
||||
Console.WriteLine("玩家死亡!");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void TakeDamage(int damage)
|
||||
{
|
||||
var playerModel = this.GetModel<PlayerModel>();
|
||||
playerModel.Health.Value -= damage;
|
||||
}
|
||||
|
||||
public void AddGold(int amount)
|
||||
{
|
||||
var playerModel = this.GetModel<PlayerModel>();
|
||||
playerModel.Gold.Value += amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Program.cs
|
||||
|
||||
```csharp
|
||||
using MyGame;
|
||||
using MyGame.Controllers;
|
||||
|
||||
var architecture = new GameArchitecture();
|
||||
architecture.Initialize();
|
||||
await architecture.WaitUntilReadyAsync();
|
||||
|
||||
var gameController = new GameController();
|
||||
gameController.InitializePlayer();
|
||||
gameController.TakeDamage(20);
|
||||
gameController.AddGold(100);
|
||||
```
|
||||
|
||||
## 运行结果
|
||||
|
||||
运行程序后,你将看到以下输出:
|
||||
|
||||
```
|
||||
玩家生命值变化: 100
|
||||
玩家生命值变化: 80
|
||||
```
|
||||
|
||||
**验证步骤**:
|
||||
1. 程序成功启动,没有异常
|
||||
2. 控制台输出生命值变化信息
|
||||
3. 玩家数据正确更新
|
||||
|
||||
## 下一步
|
||||
|
||||
恭喜!你已经学会了如何创建和使用 Model。接下来可以学习:
|
||||
|
||||
- [创建第一个 System](/zh-CN/tutorials/create-first-system) - 学习如何创建业务逻辑层
|
||||
- [使用命令系统](/zh-CN/tutorials/use-command-system) - 学习如何封装操作
|
||||
- [使用事件系统](/zh-CN/tutorials/use-event-system) - 学习组件间通信
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Model 层](/zh-CN/core/model) - Model 详细说明
|
||||
- [属性系统](/zh-CN/core/property) - 可绑定属性详解
|
||||
- [架构组件](/zh-CN/core/architecture) - 架构基础
|
||||
- [Controller 层](/zh-CN/core/controller) - Controller 详细说明
|
||||
@ -1,42 +0,0 @@
|
||||
---
|
||||
title: {{TUTORIAL_TITLE}}
|
||||
description: {{TUTORIAL_DESCRIPTION}}
|
||||
---
|
||||
|
||||
# {{TUTORIAL_TITLE}}
|
||||
|
||||
## 学习目标
|
||||
|
||||
{{LEARNING_OBJECTIVES}}
|
||||
|
||||
## 前置条件
|
||||
|
||||
{{PREREQUISITES}}
|
||||
|
||||
## 步骤 1:{{STEP_1_TITLE}}
|
||||
|
||||
{{STEP_1_CONTENT}}
|
||||
|
||||
## 步骤 2:{{STEP_2_TITLE}}
|
||||
|
||||
{{STEP_2_CONTENT}}
|
||||
|
||||
## 步骤 3:{{STEP_3_TITLE}}
|
||||
|
||||
{{STEP_3_CONTENT}}
|
||||
|
||||
## 完整代码
|
||||
|
||||
{{FULL_CODE}}
|
||||
|
||||
## 运行结果
|
||||
|
||||
{{EXPECTED_OUTPUT}}
|
||||
|
||||
## 下一步
|
||||
|
||||
{{NEXT_STEPS}}
|
||||
|
||||
## 相关文档
|
||||
|
||||
{{RELATED_DOCS}}
|
||||
@ -1,297 +0,0 @@
|
||||
# VitePress 文档验证
|
||||
|
||||
验证 VitePress 文档的质量和规范性,确保文档符合项目标准。
|
||||
|
||||
## 用途
|
||||
|
||||
此 skill 用于验证 Markdown 文档的格式和内容,包括:
|
||||
- Frontmatter 格式正确性
|
||||
- 内部链接有效性
|
||||
- 代码块语法标记
|
||||
- 标题层级结构
|
||||
- 中文标点符号规范
|
||||
- 泛型符号转义
|
||||
|
||||
## 调用方式
|
||||
|
||||
```bash
|
||||
# 验证单个文件
|
||||
/vitepress-validate <文件路径>
|
||||
|
||||
# 验证整个目录
|
||||
/vitepress-validate <目录路径>
|
||||
|
||||
# 验证所有文档
|
||||
/vitepress-validate docs/zh-CN/
|
||||
```
|
||||
|
||||
**示例**:
|
||||
```bash
|
||||
/vitepress-validate docs/zh-CN/api-reference/core/architecture.md
|
||||
/vitepress-validate docs/zh-CN/core/
|
||||
```
|
||||
|
||||
## 验证项
|
||||
|
||||
### 1. Frontmatter 验证
|
||||
|
||||
**检查项**:
|
||||
- YAML 语法正确性
|
||||
- 必需字段存在(`title`、`description`)
|
||||
- 字段值类型正确
|
||||
- `outline` 字段值有效(`deep`、`[2,3]` 等)
|
||||
|
||||
**示例**:
|
||||
```yaml
|
||||
---
|
||||
title: Architecture # 必需
|
||||
description: 架构基类说明 # 必需
|
||||
outline: deep # 可选,但值必须有效
|
||||
---
|
||||
```
|
||||
|
||||
### 2. 内部链接验证
|
||||
|
||||
**检查项**:
|
||||
- 相对路径链接指向的文件存在
|
||||
- 绝对路径链接格式正确
|
||||
- 锚点链接对应的标题存在
|
||||
- 没有损坏的链接
|
||||
|
||||
**有效链接格式**:
|
||||
- `[文本](./file.md)` - 相对路径
|
||||
- `[文本](/zh-CN/core/architecture)` - 绝对路径
|
||||
- `[文本](#标题)` - 锚点链接
|
||||
- `[文本](./file.md#标题)` - 组合链接
|
||||
|
||||
### 3. 代码块验证
|
||||
|
||||
**检查项**:
|
||||
- 代码块有语法标记(```csharp、```bash 等)
|
||||
- C# 代码块使用 `csharp` 标记(不是 `cs` 或 `c#`)
|
||||
- 代码块正确闭合
|
||||
- 没有未闭合的反引号
|
||||
|
||||
**正确格式**:
|
||||
```markdown
|
||||
\`\`\`csharp
|
||||
public class Example { }
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
**错误格式**:
|
||||
```markdown
|
||||
\`\`\`cs // 应该使用 csharp
|
||||
public class Example { }
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### 4. 标题层级验证
|
||||
|
||||
**检查项**:
|
||||
- 标题层级不跳级(不能从 `#` 直接跳到 `###`)
|
||||
- 每个文档只有一个一级标题(`#`)
|
||||
- 标题层级递增合理
|
||||
|
||||
**正确示例**:
|
||||
```markdown
|
||||
# 一级标题
|
||||
## 二级标题
|
||||
### 三级标题
|
||||
## 另一个二级标题
|
||||
```
|
||||
|
||||
**错误示例**:
|
||||
```markdown
|
||||
# 一级标题
|
||||
### 三级标题 ❌ 跳过了二级标题
|
||||
```
|
||||
|
||||
### 5. 中文标点符号验证
|
||||
|
||||
**检查项**:
|
||||
- 中文句子使用全角标点(,。!?)
|
||||
- 英文句子使用半角标点(,.!?)
|
||||
- 代码和技术术语周围使用半角符号
|
||||
- 括号使用规范
|
||||
|
||||
**规范示例**:
|
||||
- "这是一个示例。" ✓(中文全角句号)
|
||||
- "This is an example." ✓(英文半角句号)
|
||||
- "`Architecture` 类提供了..." ✓(代码周围半角)
|
||||
|
||||
### 6. 泛型符号验证
|
||||
|
||||
**检查项**:
|
||||
- 泛型符号正确转义(`<T>` → `<T>`)
|
||||
- 仅在代码块外转义
|
||||
- 代码块内保持原样
|
||||
|
||||
**正确示例**:
|
||||
```markdown
|
||||
`List<T>` 是一个泛型类。
|
||||
|
||||
\`\`\`csharp
|
||||
List<T> items = new List<T>(); // 代码块内不转义
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
## 验证脚本
|
||||
|
||||
### validate-frontmatter.sh
|
||||
|
||||
验证 Frontmatter 格式。
|
||||
|
||||
**用法**:
|
||||
```bash
|
||||
.claude/skills/vitepress-validate/scripts/validate-frontmatter.sh <文件路径>
|
||||
```
|
||||
|
||||
### validate-links.sh
|
||||
|
||||
验证内部链接有效性。
|
||||
|
||||
**用法**:
|
||||
```bash
|
||||
.claude/skills/vitepress-validate/scripts/validate-links.sh <文件路径>
|
||||
```
|
||||
|
||||
### validate-code-blocks.sh
|
||||
|
||||
验证代码块语法。
|
||||
|
||||
**用法**:
|
||||
```bash
|
||||
.claude/skills/vitepress-validate/scripts/validate-code-blocks.sh <文件路径>
|
||||
```
|
||||
|
||||
### validate-all.sh
|
||||
|
||||
执行所有验证。
|
||||
|
||||
**用法**:
|
||||
```bash
|
||||
.claude/skills/vitepress-validate/scripts/validate-all.sh <文件或目录路径>
|
||||
```
|
||||
|
||||
## 输出格式
|
||||
|
||||
### 验证通过
|
||||
|
||||
```
|
||||
✓ docs/zh-CN/core/architecture.md
|
||||
- Frontmatter: 通过
|
||||
- 内部链接: 通过
|
||||
- 代码块: 通过
|
||||
- 标题层级: 通过
|
||||
- 标点符号: 通过
|
||||
- 泛型符号: 通过
|
||||
```
|
||||
|
||||
### 验证失败
|
||||
|
||||
```
|
||||
✗ docs/zh-CN/core/architecture.md
|
||||
- Frontmatter: 失败
|
||||
× 缺少必需字段: description
|
||||
- 内部链接: 失败
|
||||
× 损坏的链接: ./missing-file.md (第 45 行)
|
||||
- 代码块: 警告
|
||||
⚠ 使用了 'cs' 标记,建议使用 'csharp' (第 78 行)
|
||||
- 标题层级: 通过
|
||||
- 标点符号: 警告
|
||||
⚠ 中文句子使用了半角句号 (第 102 行)
|
||||
- 泛型符号: 失败
|
||||
× 未转义的泛型符号: List<T> (第 120 行)
|
||||
```
|
||||
|
||||
## 修复建议
|
||||
|
||||
验证失败时,skill 会提供具体的修复建议:
|
||||
|
||||
**示例**:
|
||||
```
|
||||
修复建议:
|
||||
1. 在 Frontmatter 中添加 description 字段
|
||||
2. 修复或删除损坏的链接: ./missing-file.md
|
||||
3. 将代码块标记从 'cs' 改为 'csharp'
|
||||
4. 将第 102 行的半角句号改为全角句号
|
||||
5. 将第 120 行的 List<T> 改为 List<T>
|
||||
```
|
||||
|
||||
## 配置选项
|
||||
|
||||
### 严格模式
|
||||
|
||||
启用严格模式时,警告也会导致验证失败。
|
||||
|
||||
```bash
|
||||
/vitepress-validate --strict docs/zh-CN/
|
||||
```
|
||||
|
||||
### 忽略特定检查
|
||||
|
||||
```bash
|
||||
# 忽略标点符号检查
|
||||
/vitepress-validate --ignore-punctuation docs/zh-CN/
|
||||
|
||||
# 忽略多个检查
|
||||
/vitepress-validate --ignore-punctuation --ignore-generics docs/zh-CN/
|
||||
```
|
||||
|
||||
## 集成到工作流
|
||||
|
||||
### 生成后自动验证
|
||||
|
||||
```bash
|
||||
# 1. 生成 API 文档
|
||||
/vitepress-api-doc GFramework.Core/architecture/Architecture.cs
|
||||
|
||||
# 2. 自动验证生成的文档
|
||||
/vitepress-validate docs/zh-CN/api-reference/core/architecture.md
|
||||
```
|
||||
|
||||
### 批量验证
|
||||
|
||||
```bash
|
||||
# 验证所有 API 文档
|
||||
/vitepress-validate docs/zh-CN/api-reference/
|
||||
|
||||
# 验证所有文档
|
||||
/vitepress-validate docs/zh-CN/
|
||||
```
|
||||
|
||||
## 退出代码
|
||||
|
||||
- `0` - 所有验证通过
|
||||
- `1` - 存在错误
|
||||
- `2` - 仅存在警告(非严格模式下仍返回 0)
|
||||
|
||||
## 相关 Skills
|
||||
|
||||
- `/vitepress-api-doc` - 生成 API 文档后自动验证
|
||||
- `/vitepress-guide` - 生成指南文档后自动验证
|
||||
- `/vitepress-tutorial` - 生成教程文档后自动验证
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **生成后立即验证**:每次生成文档后立即运行验证
|
||||
2. **定期批量验证**:定期验证所有文档,确保一致性
|
||||
3. **修复所有错误**:不要忽略验证错误,及时修复
|
||||
4. **关注警告**:警告虽不致命,但应该重视并修复
|
||||
5. **使用严格模式**:在 CI/CD 中使用严格模式确保质量
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 问题:误报泛型符号错误
|
||||
**解决方案**:确保泛型符号在代码块外正确转义,代码块内保持原样
|
||||
|
||||
### 问题:中文标点符号检查过于严格
|
||||
**解决方案**:使用 `--ignore-punctuation` 选项,或手动调整规则
|
||||
|
||||
### 问题:链接验证失败但文件确实存在
|
||||
**解决方案**:检查文件路径大小写,确保路径完全匹配
|
||||
|
||||
## 版本历史
|
||||
|
||||
- v1.0.0 - 初始版本,支持 6 项基本验证
|
||||
@ -1,109 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 执行所有验证
|
||||
# 用法: validate-all.sh <文件或目录路径>
|
||||
|
||||
set -e
|
||||
|
||||
TARGET="$1"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
if [ -z "$TARGET" ]; then
|
||||
echo "用法: $0 <文件或目录路径>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -e "$TARGET" ]; then
|
||||
echo "错误: 路径不存在: $TARGET"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=========================================="
|
||||
echo "VitePress 文档验证"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# 收集所有 Markdown 文件
|
||||
if [ -f "$TARGET" ]; then
|
||||
FILES=("$TARGET")
|
||||
elif [ -d "$TARGET" ]; then
|
||||
mapfile -t FILES < <(find "$TARGET" -name "*.md" -type f)
|
||||
else
|
||||
echo "错误: 无效的路径: $TARGET"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ${#FILES[@]} -eq 0 ]; then
|
||||
echo "未找到 Markdown 文件"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "找到 ${#FILES[@]} 个文件"
|
||||
echo ""
|
||||
|
||||
TOTAL_ERRORS=0
|
||||
TOTAL_WARNINGS=0
|
||||
PASSED_FILES=0
|
||||
FAILED_FILES=0
|
||||
|
||||
for FILE in "${FILES[@]}"; do
|
||||
echo "验证: $FILE"
|
||||
echo "----------------------------------------"
|
||||
|
||||
FILE_ERRORS=0
|
||||
FILE_WARNINGS=0
|
||||
|
||||
# 1. Frontmatter 验证
|
||||
if bash "$SCRIPT_DIR/validate-frontmatter.sh" "$FILE" 2>&1 | grep -q "✗"; then
|
||||
FILE_ERRORS=$((FILE_ERRORS + 1))
|
||||
fi
|
||||
|
||||
# 2. 链接验证
|
||||
if bash "$SCRIPT_DIR/validate-links.sh" "$FILE" 2>&1 | grep -q "✗"; then
|
||||
FILE_ERRORS=$((FILE_ERRORS + 1))
|
||||
fi
|
||||
|
||||
# 3. 代码块验证
|
||||
OUTPUT=$(bash "$SCRIPT_DIR/validate-code-blocks.sh" "$FILE" 2>&1 || true)
|
||||
if echo "$OUTPUT" | grep -q "✗"; then
|
||||
FILE_ERRORS=$((FILE_ERRORS + 1))
|
||||
fi
|
||||
if echo "$OUTPUT" | grep -q "⚠"; then
|
||||
FILE_WARNINGS=$((FILE_WARNINGS + 1))
|
||||
fi
|
||||
|
||||
# 统计结果
|
||||
if [ $FILE_ERRORS -eq 0 ]; then
|
||||
echo "✓ 验证通过"
|
||||
PASSED_FILES=$((PASSED_FILES + 1))
|
||||
else
|
||||
echo "✗ 验证失败($FILE_ERRORS 个错误)"
|
||||
FAILED_FILES=$((FAILED_FILES + 1))
|
||||
fi
|
||||
|
||||
if [ $FILE_WARNINGS -gt 0 ]; then
|
||||
echo "⚠ $FILE_WARNINGS 个警告"
|
||||
fi
|
||||
|
||||
TOTAL_ERRORS=$((TOTAL_ERRORS + FILE_ERRORS))
|
||||
TOTAL_WARNINGS=$((TOTAL_WARNINGS + FILE_WARNINGS))
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "=========================================="
|
||||
echo "验证摘要"
|
||||
echo "=========================================="
|
||||
echo "总文件数: ${#FILES[@]}"
|
||||
echo "通过: $PASSED_FILES"
|
||||
echo "失败: $FAILED_FILES"
|
||||
echo "总错误数: $TOTAL_ERRORS"
|
||||
echo "总警告数: $TOTAL_WARNINGS"
|
||||
echo ""
|
||||
|
||||
if [ $TOTAL_ERRORS -eq 0 ]; then
|
||||
echo "✓ 所有验证通过"
|
||||
exit 0
|
||||
else
|
||||
echo "✗ 验证失败"
|
||||
exit 1
|
||||
fi
|
||||
@ -1,64 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 验证代码块语法
|
||||
# 用法: validate-code-blocks.sh <文件路径>
|
||||
|
||||
set -e
|
||||
|
||||
FILE="$1"
|
||||
|
||||
if [ -z "$FILE" ]; then
|
||||
echo "用法: $0 <文件路径>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$FILE" ]; then
|
||||
echo "错误: 文件不存在: $FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "验证代码块语法: $FILE"
|
||||
|
||||
ERROR_COUNT=0
|
||||
WARNING_COUNT=0
|
||||
|
||||
# 检查未闭合的代码块
|
||||
OPEN_COUNT=$(grep -c '^```' "$FILE" || true)
|
||||
if [ $((OPEN_COUNT % 2)) -ne 0 ]; then
|
||||
echo "✗ 错误: 存在未闭合的代码块"
|
||||
ERROR_COUNT=$((ERROR_COUNT + 1))
|
||||
fi
|
||||
|
||||
# 检查 C# 代码块标记
|
||||
LINE_NUM=0
|
||||
while IFS= read -r LINE; do
|
||||
LINE_NUM=$((LINE_NUM + 1))
|
||||
|
||||
# 检查是否使用了错误的 C# 标记
|
||||
if echo "$LINE" | grep -qE '^```(cs|c#|C#)$'; then
|
||||
echo "⚠ 警告: 第 $LINE_NUM 行使用了非标准标记,建议使用 'csharp'"
|
||||
echo " 当前: $LINE"
|
||||
WARNING_COUNT=$((WARNING_COUNT + 1))
|
||||
fi
|
||||
|
||||
# 检查代码块是否有语言标记
|
||||
if echo "$LINE" | grep -qE '^```$'; then
|
||||
# 检查下一行是否是代码(简单启发式:不是空行且不是 ```)
|
||||
NEXT_LINE=$(sed -n "$((LINE_NUM + 1))p" "$FILE")
|
||||
if [ -n "$NEXT_LINE" ] && ! echo "$NEXT_LINE" | grep -qE '^```'; then
|
||||
echo "⚠ 警告: 第 $LINE_NUM 行的代码块缺少语言标记"
|
||||
WARNING_COUNT=$((WARNING_COUNT + 1))
|
||||
fi
|
||||
fi
|
||||
done < "$FILE"
|
||||
|
||||
# 输出结果
|
||||
if [ $ERROR_COUNT -eq 0 ] && [ $WARNING_COUNT -eq 0 ]; then
|
||||
echo "✓ 代码块验证通过"
|
||||
exit 0
|
||||
elif [ $ERROR_COUNT -eq 0 ]; then
|
||||
echo "⚠ 代码块验证通过(有 $WARNING_COUNT 个警告)"
|
||||
exit 0
|
||||
else
|
||||
echo "✗ 代码块验证失败($ERROR_COUNT 个错误,$WARNING_COUNT 个警告)"
|
||||
exit 1
|
||||
fi
|
||||
@ -1,57 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 验证 Frontmatter 格式
|
||||
# 用法: validate-frontmatter.sh <文件路径>
|
||||
|
||||
set -e
|
||||
|
||||
FILE="$1"
|
||||
|
||||
if [ -z "$FILE" ]; then
|
||||
echo "用法: $0 <文件路径>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$FILE" ]; then
|
||||
echo "错误: 文件不存在: $FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "验证 Frontmatter: $FILE"
|
||||
|
||||
# 检查是否有 Frontmatter(限制在前几行,避免匹配正文中的 '---')
|
||||
if ! head -n 5 "$FILE" | grep -q "^---$"; then
|
||||
echo "✗ 错误: 文件缺少 Frontmatter"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 提取 Frontmatter 内容(第一个 --- 到第二个 --- 之间)
|
||||
FRONTMATTER=$(sed -n '/^---$/,/^---$/p' "$FILE" | sed '1d;$d')
|
||||
|
||||
if [ -z "$FRONTMATTER" ]; then
|
||||
echo "✗ 错误: Frontmatter 为空"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查必需字段: title
|
||||
if ! echo "$FRONTMATTER" | grep -q "^title:"; then
|
||||
echo "✗ 错误: 缺少必需字段: title"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查必需字段: description
|
||||
if ! echo "$FRONTMATTER" | grep -q "^description:"; then
|
||||
echo "✗ 错误: 缺少必需字段: description"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查 outline 字段值(如果存在)
|
||||
if echo "$FRONTMATTER" | grep -q "^outline:"; then
|
||||
OUTLINE_VALUE=$(echo "$FRONTMATTER" | grep "^outline:" | sed 's/outline:\s*//')
|
||||
if [ "$OUTLINE_VALUE" != "deep" ] && [ "$OUTLINE_VALUE" != "false" ] && ! echo "$OUTLINE_VALUE" | grep -qE '^\[.*\]$'; then
|
||||
echo "⚠ 警告: outline 字段值可能无效: $OUTLINE_VALUE"
|
||||
echo " 有效值: deep, false, [2,3]"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✓ Frontmatter 验证通过"
|
||||
exit 0
|
||||
@ -1,85 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 验证内部链接有效性
|
||||
# 用法: validate-links.sh <文件路径>
|
||||
|
||||
set -e
|
||||
|
||||
FILE="$1"
|
||||
BASE_DIR="docs/zh-CN"
|
||||
|
||||
if [ -z "$FILE" ]; then
|
||||
echo "用法: $0 <文件路径>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$FILE" ]; then
|
||||
echo "错误: 文件不存在: $FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "验证内部链接: $FILE"
|
||||
|
||||
# 获取文件所在目录
|
||||
FILE_DIR=$(dirname "$FILE")
|
||||
|
||||
# 提取所有 Markdown 链接
|
||||
LINKS=$(grep -oP '\[([^\]]+)\]\(([^)]+)\)' "$FILE" | grep -oP '\(([^)]+)\)' | sed 's/[()]//g' || true)
|
||||
|
||||
if [ -z "$LINKS" ]; then
|
||||
echo "✓ 未找到链接"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ERROR_COUNT=0
|
||||
|
||||
while IFS= read -r LINK; do
|
||||
# 跳过外部链接
|
||||
if [[ "$LINK" =~ ^https?:// ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# 跳过锚点链接(仅 #开头)
|
||||
if [[ "$LINK" =~ ^# ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# 移除锚点部分
|
||||
LINK_PATH=$(echo "$LINK" | sed 's/#.*//')
|
||||
|
||||
# 跳过空路径
|
||||
if [ -z "$LINK_PATH" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# 处理相对路径
|
||||
if [[ "$LINK_PATH" =~ ^\. ]]; then
|
||||
TARGET="$FILE_DIR/$LINK_PATH"
|
||||
# 处理绝对路径
|
||||
elif [[ "$LINK_PATH" =~ ^/ ]]; then
|
||||
TARGET="docs$LINK_PATH"
|
||||
# 如果没有扩展名,尝试添加 .md
|
||||
if [[ ! "$TARGET" =~ \. ]]; then
|
||||
TARGET="$TARGET.md"
|
||||
fi
|
||||
else
|
||||
TARGET="$FILE_DIR/$LINK_PATH"
|
||||
fi
|
||||
|
||||
# 规范化路径
|
||||
TARGET=$(realpath -m "$TARGET" 2>/dev/null || echo "$TARGET")
|
||||
|
||||
# 检查文件是否存在
|
||||
if [ ! -f "$TARGET" ] && [ ! -d "$TARGET" ]; then
|
||||
echo "✗ 损坏的链接: $LINK"
|
||||
echo " 目标不存在: $TARGET"
|
||||
ERROR_COUNT=$((ERROR_COUNT + 1))
|
||||
fi
|
||||
done <<< "$LINKS"
|
||||
|
||||
if [ $ERROR_COUNT -eq 0 ]; then
|
||||
echo "✓ 内部链接验证通过"
|
||||
exit 0
|
||||
else
|
||||
echo "✗ 发现 $ERROR_COUNT 个损坏的链接"
|
||||
exit 1
|
||||
fi
|
||||
@ -1,13 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnetctrfjsonreporter": {
|
||||
"version": "0.0.7",
|
||||
"commands": [
|
||||
"DotnetCtrfJsonReporter"
|
||||
],
|
||||
"rollForward": false
|
||||
}
|
||||
}
|
||||
}
|
||||
11
.feluda.yaml
11
.feluda.yaml
@ -1,11 +0,0 @@
|
||||
license_overrides:
|
||||
NETStandard.Library: MIT
|
||||
Microsoft.NETCore.Platforms: MIT
|
||||
System.Buffers: MIT
|
||||
System.Memory: MIT
|
||||
System.Numerics.Vectors: MIT
|
||||
System.Threading.Tasks.Extensions: MIT
|
||||
System.ComponentModel.Composition: MIT
|
||||
System.Security.Cryptography.ProtectedData: MIT
|
||||
System.Security.Permissions: MIT
|
||||
Microsoft.VisualStudio.Validation: MIT
|
||||
19
.github/dependabot.yml
vendored
19
.github/dependabot.yml
vendored
@ -1,19 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
# ===== NuGet 依赖(所有项目)=====
|
||||
- package-ecosystem: "nuget"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 5
|
||||
ignore:
|
||||
# 忽略所有依赖的大版本升级(框架项目非常建议)
|
||||
- dependency-name: "*"
|
||||
update-types:
|
||||
- "version-update:semver-major"
|
||||
|
||||
# ===== GitHub Actions =====
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
132
.github/workflows/auto-tag.yml
vendored
132
.github/workflows/auto-tag.yml
vendored
@ -1,64 +1,112 @@
|
||||
name: Auto Increment Version and Tag
|
||||
|
||||
# 工作流触发条件配置
|
||||
# 当向 main 或 master 分支推送代码时触发
|
||||
# 或者当针对 main 或 master 的 PR 被合并关闭时触发
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["CI - Build & Test"]
|
||||
types:
|
||||
- completed
|
||||
workflow_dispatch:
|
||||
concurrency:
|
||||
group: auto-tag-main
|
||||
cancel-in-progress: false
|
||||
push:
|
||||
branches: [ main, master ]
|
||||
pull_request:
|
||||
branches: [ main, master ]
|
||||
types: [ closed ]
|
||||
|
||||
jobs:
|
||||
auto-tag:
|
||||
if: >
|
||||
github.ref == 'refs/heads/main' &&
|
||||
(
|
||||
(
|
||||
github.event_name == 'workflow_run' &&
|
||||
github.event.workflow_run.conclusion == 'success' &&
|
||||
contains(github.event.workflow_run.head_commit.message, '[release ci]')
|
||||
)
|
||||
||
|
||||
github.event_name == 'workflow_dispatch'
|
||||
)
|
||||
|
||||
name: Auto Increment Version and Create Tag
|
||||
runs-on: ubuntu-latest
|
||||
# 条件判断:仅在推送事件或已合并的 PR 关闭事件中执行
|
||||
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true)
|
||||
permissions:
|
||||
contents: write
|
||||
outputs:
|
||||
tagged: ${{ steps.create_tag.outcome == 'success' }}
|
||||
|
||||
steps:
|
||||
# 步骤一:检出仓库代码
|
||||
# 使用 actions/checkout 动作获取完整的 Git 历史用于查找已有标签
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
lfs: true
|
||||
fetch-depth: 0 # 获取全部历史记录以查找现有标签
|
||||
persist-credentials: false
|
||||
|
||||
- name: Get next version
|
||||
id: version
|
||||
# 步骤二:检查是否需要跳过打标签操作
|
||||
# 根据最新提交信息决定是否继续后续流程
|
||||
- name: Check for skip keyword
|
||||
id: check_skip
|
||||
run: |
|
||||
LATEST_TAG=$(git tag --list "v*" --sort=-v:refname | head -n 1)
|
||||
LATEST_TAG=${LATEST_TAG:-v0.0.0}
|
||||
VERSION=${LATEST_TAG#v}
|
||||
IFS=. read MAJOR MINOR PATCH <<< "$VERSION"
|
||||
PATCH=$((PATCH+1))
|
||||
echo "new_tag=v$MAJOR.$MINOR.$PATCH" >> $GITHUB_OUTPUT
|
||||
# 检查最近一次提交信息是否包含跳过关键词
|
||||
LAST_COMMIT_MSG=$(git log -1 --pretty=format:"%B")
|
||||
if [[ "$LAST_COMMIT_MSG" == *"[skip release]"* ]] || [[ "$LAST_COMMIT_MSG" == *"[no tag]"* ]]; then
|
||||
echo "skip_tag=true" >> $GITHUB_OUTPUT
|
||||
echo "Skipping tag creation due to skip keyword in commit message"
|
||||
else
|
||||
echo "skip_tag=false" >> $GITHUB_OUTPUT
|
||||
echo "No skip keyword found, proceeding with tag creation"
|
||||
fi
|
||||
echo "Last commit message: $LAST_COMMIT_MSG"
|
||||
|
||||
- name: Create tag
|
||||
# 步骤三:计算下一个版本号(若未被跳过)
|
||||
# 自动解析当前最新标签并递增修订号生成新的语义化版本号
|
||||
- name: Get next version
|
||||
id: get_next_version
|
||||
if: steps.check_skip.outputs.skip_tag == 'false'
|
||||
run: |
|
||||
# 获取最新的标签版本号,如果没有标签则默认为 0.0.0
|
||||
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
|
||||
|
||||
# 移除可能存在的 v 前缀
|
||||
VERSION_NUM=${LATEST_TAG#v}
|
||||
|
||||
# 解析主版本号、次版本号和修订号
|
||||
MAJOR=$(echo $VERSION_NUM | cut -d. -f1)
|
||||
MINOR=$(echo $VERSION_NUM | cut -d. -f2)
|
||||
PATCH=$(echo $VERSION_NUM | cut -d. -f3)
|
||||
|
||||
# 递增修订号
|
||||
PATCH=$((PATCH + 1))
|
||||
|
||||
# 构造新版本号
|
||||
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
|
||||
NEW_TAG="v$NEW_VERSION"
|
||||
|
||||
echo "latest_tag=$LATEST_TAG"
|
||||
echo "new_version=$NEW_VERSION"
|
||||
echo "new_tag=$NEW_TAG"
|
||||
|
||||
echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
|
||||
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
||||
echo "new_tag=$NEW_TAG" >> $GITHUB_OUTPUT
|
||||
|
||||
# 步骤四:创建并推送新标签到远程仓库(若未被跳过)
|
||||
# 使用个人访问令牌(PAT)进行身份验证完成推送操作
|
||||
- name: Create tag and push (using PAT)
|
||||
if: steps.check_skip.outputs.skip_tag == 'false'
|
||||
env:
|
||||
PAT: ${{ secrets.PAT_TOKEN }}
|
||||
TAG: ${{ steps.version.outputs.new_tag }}
|
||||
REPO: ${{ github.repository }}
|
||||
NEW_TAG: ${{ steps.get_next_version.outputs.new_tag }}
|
||||
run: |
|
||||
set -e
|
||||
git config user.name "GitHub Action"
|
||||
git config user.email "action@github.com"
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
|
||||
if git show-ref --tags --verify --quiet "refs/tags/$TAG"; then
|
||||
echo "Tag $TAG already exists, skipping"
|
||||
exit 0
|
||||
fi
|
||||
echo "Creating annotated tag $NEW_TAG"
|
||||
git tag -a "$NEW_TAG" -m "Auto-generated tag: $NEW_TAG"
|
||||
|
||||
git tag -a "$TAG" -m "Auto tag $TAG"
|
||||
git push "https://x-access-token:${PAT}@github.com/${{ github.repository }}.git" "$TAG"
|
||||
# 推送单个 tag,使用 PAT 作为 HTTPS token
|
||||
echo "Pushing tag $NEW_TAG to origin using PAT"
|
||||
git push "https://x-access-token:${PAT}@github.com/${REPO}.git" "refs/tags/${NEW_TAG}"
|
||||
|
||||
# 步骤五:输出本次成功创建的新版本相关信息(若未被跳过)
|
||||
- name: Print version info
|
||||
if: steps.check_skip.outputs.skip_tag == 'false'
|
||||
run: |
|
||||
echo "Previous tag was: ${{ steps.get_next_version.outputs.latest_tag }}"
|
||||
echo "New tag created: ${{ steps.get_next_version.outputs.new_tag }}"
|
||||
echo "Version number: ${{ steps.get_next_version.outputs.new_version }}"
|
||||
|
||||
# 步骤六:输出跳过原因信息(如果检测到了跳过关键字)
|
||||
- name: Print skip info
|
||||
if: steps.check_skip.outputs.skip_tag == 'true'
|
||||
run: |
|
||||
echo "Tag creation skipped due to commit message containing skip keyword"
|
||||
|
||||
201
.github/workflows/ci.yml
vendored
201
.github/workflows/ci.yml
vendored
@ -1,201 +0,0 @@
|
||||
# CI/CD工作流配置:构建和测试.NET项目
|
||||
# 该工作流在push到main/master分支或创建pull request时触发
|
||||
name: CI - Build & Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, master ]
|
||||
pull_request:
|
||||
branches: [ main, master ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
# 代码质量检查 job(并行执行,不阻塞构建)
|
||||
code-quality:
|
||||
name: Code Quality & Security
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# 检出源代码,设置fetch-depth为0以获取完整的git历史
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# 校验C#命名空间与源码目录是否符合命名规范
|
||||
- name: Validate C# naming
|
||||
run: bash scripts/validate-csharp-naming.sh
|
||||
|
||||
# 缓存MegaLinter
|
||||
- name: Cache MegaLinter
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/.cache/megalinter
|
||||
key: ${{ runner.os }}-megalinter-v9
|
||||
restore-keys: |
|
||||
${{ runner.os }}-megalinter-
|
||||
|
||||
# MegaLinter扫描步骤
|
||||
# 执行代码质量检查和安全扫描,生成SARIF格式报告
|
||||
- name: MegaLinter
|
||||
uses: oxsecurity/megalinter@v9.4.0
|
||||
continue-on-error: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
FAIL_ON_ERROR: ${{ github.ref == 'refs/heads/main' }}
|
||||
|
||||
# 上传SARIF格式的安全和代码质量问题报告到GitHub安全中心
|
||||
- name: Upload SARIF
|
||||
uses: github/codeql-action/upload-sarif@v4
|
||||
with:
|
||||
sarif_file: megalinter-reports/sarif
|
||||
|
||||
# 缓存TruffleHog
|
||||
- name: Cache TruffleHog
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/.cache/trufflehog
|
||||
key: ${{ runner.os }}-trufflehog
|
||||
|
||||
# TruffleHog OSS 扫描步骤
|
||||
# 使用 TruffleHog 工具扫描代码库中的敏感信息泄露,如API密钥、密码等
|
||||
# 该步骤会比较基础分支和当前提交之间的差异,检测新增内容中是否包含敏感数据
|
||||
- name: TruffleHog OSS
|
||||
uses: trufflesecurity/trufflehog@v3.93.8
|
||||
with:
|
||||
# 扫描路径,. 表示扫描整个仓库
|
||||
path: .
|
||||
# 基础提交哈希,用于与当前提交进行比较
|
||||
base: ${{ github.event.before }}
|
||||
# 当前提交哈希,作为扫描的目标版本
|
||||
head: ${{ github.sha }}
|
||||
|
||||
# 构建和测试 job(并行执行)
|
||||
build-and-test:
|
||||
name: Build and Test
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# 检出源代码
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# 安装和配置.NET SDK版本
|
||||
- name: Setup .NET 8
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: 8.0.x
|
||||
|
||||
- name: Setup .NET 9
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Setup .NET 10
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: 10.0.x
|
||||
|
||||
# 配置NuGet包缓存以加速后续构建
|
||||
- name: Cache NuGet packages
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.nuget/packages
|
||||
~/.local/share/NuGet
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/nuget.config') }}
|
||||
|
||||
# 配置.NET本地工具缓存以加速后续构建
|
||||
- name: Cache dotnet tools
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/.dotnet/tools
|
||||
key: ${{ runner.os }}-dotnet-tools-${{ hashFiles('.config/dotnet-tools.json') }}
|
||||
|
||||
# 执行NuGet包恢复操作
|
||||
- name: Restore
|
||||
run: dotnet restore
|
||||
# 恢复.NET本地工具
|
||||
- name: Restore .NET tools
|
||||
run: dotnet tool restore
|
||||
|
||||
# 构建项目,使用Release配置且跳过恢复步骤
|
||||
- name: Build
|
||||
run: dotnet build -c Release --no-restore
|
||||
|
||||
# 运行单元测试,输出TRX格式结果到TestResults目录
|
||||
# 在同一个 step 中并发执行所有测试以加快速度
|
||||
- name: Test All Projects
|
||||
run: |
|
||||
dotnet test GFramework.Core.Tests \
|
||||
-c Release \
|
||||
--no-build \
|
||||
--logger "trx;LogFileName=core-$RANDOM.trx" \
|
||||
--results-directory TestResults &
|
||||
|
||||
dotnet test GFramework.Game.Tests \
|
||||
-c Release \
|
||||
--no-build \
|
||||
--logger "trx;LogFileName=game-$RANDOM.trx" \
|
||||
--results-directory TestResults &
|
||||
|
||||
dotnet test GFramework.SourceGenerators.Tests \
|
||||
-c Release \
|
||||
--no-build \
|
||||
--logger "trx;LogFileName=sg-$RANDOM.trx" \
|
||||
--results-directory TestResults &
|
||||
|
||||
dotnet test GFramework.Ecs.Arch.Tests \
|
||||
-c Release \
|
||||
--no-build \
|
||||
--logger "trx;LogFileName=ecs-arch-$RANDOM.trx" \
|
||||
--results-directory TestResults &
|
||||
|
||||
# 等待所有后台测试完成
|
||||
wait
|
||||
|
||||
- name: Generate CTRF report
|
||||
run: |
|
||||
mkdir -p ctrf
|
||||
|
||||
for trx in TestResults/*.trx; do
|
||||
name=$(basename "$trx" .trx)
|
||||
echo "Processing $trx -> ctrf/$name.json"
|
||||
|
||||
dotnet tool run DotnetCtrfJsonReporter \
|
||||
-p "$trx" \
|
||||
-t nunit \
|
||||
-d ctrf \
|
||||
-f "$name.json"
|
||||
done
|
||||
|
||||
|
||||
# 生成并发布测试报告,无论测试成功或失败都会执行
|
||||
- name: Test Report
|
||||
uses: dorny/test-reporter@v2
|
||||
if: always()
|
||||
with:
|
||||
name: .NET Test Results
|
||||
path: TestResults/*.trx
|
||||
reporter: dotnet-trx
|
||||
- name: Publish Test Report
|
||||
uses: ctrf-io/github-test-reporter@v1
|
||||
with:
|
||||
report-path: './ctrf/*.json'
|
||||
github-report: true
|
||||
pull-request-report: true
|
||||
summary-delta-report: true
|
||||
insights-report: true
|
||||
flaky-rate-report: true
|
||||
fail-rate-report: true
|
||||
slowest-report: true
|
||||
upload-artifact: true
|
||||
fetch-previous-results: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
if: always()
|
||||
53
.github/workflows/codeql.yml
vendored
53
.github/workflows/codeql.yml
vendored
@ -1,53 +0,0 @@
|
||||
# GitHub Actions工作流配置:CodeQL静态代码分析
|
||||
# 该工作流用于对C#项目进行安全漏洞和代码质量分析
|
||||
name: "CodeQL"
|
||||
|
||||
# 触发事件配置
|
||||
# 在以下情况下触发工作流:
|
||||
# 1. 推送到main分支时
|
||||
# 2. 针对main分支的拉取请求时
|
||||
# 3. 每天凌晨2点执行一次
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
schedule:
|
||||
- cron: '0 2 * * *'
|
||||
|
||||
jobs:
|
||||
# 分析任务配置
|
||||
# 对C#代码进行静态分析扫描
|
||||
analyze:
|
||||
name: Analyze (C#)
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# 设置.NET运行时环境
|
||||
# 配置.NET 8.0.x版本支持
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: |
|
||||
8.0.x
|
||||
|
||||
# 初始化CodeQL分析环境
|
||||
# 配置C#语言支持并启用自动构建模式
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
with:
|
||||
languages: csharp
|
||||
build-mode: autobuild
|
||||
|
||||
# 执行CodeQL代码分析
|
||||
# 运行静态分析并生成结果报告
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4
|
||||
117
.github/workflows/license-compliance.yml
vendored
117
.github/workflows/license-compliance.yml
vendored
@ -1,117 +0,0 @@
|
||||
name: License Compliance (Feluda)
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
compliance:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# 使用Feluda许可证扫描器检查项目依赖的许可证合规性
|
||||
# 配置参数:
|
||||
# - project-license: 设置项目许可证为Apache-2.0
|
||||
# - fail-on-restrictive: 发现限制性许可证时失败
|
||||
# - fail-on-incompatible: 发现不兼容许可证时失败
|
||||
# - update-badge: 自动更新许可证徽章
|
||||
- name: Feluda License Scanner
|
||||
uses: anistark/feluda@v1.11.1
|
||||
with:
|
||||
project-license: 'Apache-2.0'
|
||||
fail-on-restrictive: false
|
||||
fail-on-incompatible: false
|
||||
update-badge: startsWith(github.ref, 'refs/tags/v')
|
||||
- name: Feluda License Scanner Incompatible Licenses
|
||||
run: |
|
||||
feluda --incompatible
|
||||
|
||||
# 生成合规性文件(NOTICE / THIRD_PARTY_LICENSES)
|
||||
- name: Generate compliance files
|
||||
run: |
|
||||
echo "1" | feluda generate
|
||||
echo "2" | feluda generate
|
||||
|
||||
# 生成 SBOM(SPDX + CycloneDX)
|
||||
- name: Generate SBOM
|
||||
run: |
|
||||
feluda sbom spdx --output sbom.spdx.json
|
||||
feluda sbom cyclonedx --output sbom.cyclonedx.json
|
||||
|
||||
# 校验 SBOM
|
||||
- name: Validate SBOM files
|
||||
run: |
|
||||
feluda sbom validate sbom.spdx.json --output sbom-spdx-validation.txt
|
||||
feluda sbom validate sbom.cyclonedx.json --output sbom-cyclonedx-validation.txt
|
||||
|
||||
# 上传合规产物到 GitHub Actions 工件存储
|
||||
# 此步骤将指定的合规文件打包并上传为工件,供后续流程使用
|
||||
# 参数说明:
|
||||
# name: 步骤名称,用于标识该操作
|
||||
# uses: 指定使用的 GitHub Action,此处为上传工件的官方动作
|
||||
# with: 配置上传的具体内容
|
||||
# name: 工件名称,用于标识上传的文件集合
|
||||
# path: 指定需要上传的文件路径列表(支持多行格式)
|
||||
- name: Upload compliance artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: license-compliance
|
||||
path: |
|
||||
NOTICE
|
||||
THIRD_PARTY_LICENSES.md
|
||||
sbom.spdx.json
|
||||
sbom.cyclonedx.json
|
||||
sbom-spdx-validation.txt
|
||||
sbom-cyclonedx-validation.txt
|
||||
|
||||
# 将合规文件打包为 ZIP 压缩包
|
||||
# 此步骤通过 zip 命令将多个合规文件压缩为一个 ZIP 文件,便于分发或存档
|
||||
# 压缩包中包含以下文件:
|
||||
# - NOTICE: 项目声明文件
|
||||
# - THIRD_PARTY_LICENSES.md: 第三方许可证列表
|
||||
# - sbom.spdx.json: SPDX 格式的软件物料清单
|
||||
# - sbom.cyclonedx.json: CycloneDX 格式的软件物料清单
|
||||
# - sbom-spdx-validation.txt: SPDX 格式验证结果
|
||||
# - sbom-cyclonedx-validation.txt: CycloneDX 格式验证结果
|
||||
- name: Package compliance bundle
|
||||
run: |
|
||||
zip license-compliance.zip \
|
||||
NOTICE \
|
||||
THIRD_PARTY_LICENSES.md \
|
||||
sbom.spdx.json \
|
||||
sbom.cyclonedx.json \
|
||||
sbom-spdx-validation.txt \
|
||||
sbom-cyclonedx-validation.txt
|
||||
|
||||
|
||||
|
||||
# 将合规产物上传至 GitHub Release
|
||||
# 此步骤将指定的合规文件附加到当前标签对应的 GitHub Release 中
|
||||
# 参数说明:
|
||||
# name: 步骤名称,用于标识该操作
|
||||
# uses: 指定使用的 GitHub Action,此处为发布 Release 的第三方动作
|
||||
# with: 配置发布的具体信息
|
||||
# tag_name: 指定 Release 对应的 Git 标签名
|
||||
# files: 指定需要附加到 Release 的文件路径列表(支持多行格式)
|
||||
# env: 设置环境变量
|
||||
# GITHUB_TOKEN: GitHub 访问令牌,用于授权发布操作
|
||||
- name: Upload compliance assets to GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ github.ref_name }}
|
||||
files: |
|
||||
NOTICE
|
||||
THIRD_PARTY_LICENSES.md
|
||||
sbom.spdx.json
|
||||
sbom.cyclonedx.json
|
||||
sbom-spdx-validation.txt
|
||||
sbom-cyclonedx-validation.txt
|
||||
license-compliance.zip
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
84
.github/workflows/publish-docs.yml
vendored
84
.github/workflows/publish-docs.yml
vendored
@ -1,84 +0,0 @@
|
||||
# 工作流名称:Publish Docs
|
||||
# 该工作流用于在推送标签或手动触发时构建并部署文档到 GitHub Pages
|
||||
|
||||
name: Publish Docs
|
||||
|
||||
# 触发条件配置
|
||||
# 当推送以 'v' 开头的标签时触发,或者通过 GitHub UI 手动触发
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
# 权限配置
|
||||
# 配置工作流所需的权限:
|
||||
# - contents: read(读取仓库内容)
|
||||
# - pages: write(写入 GitHub Pages)
|
||||
# - id-token: write(写入身份令牌)
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# 并发控制配置
|
||||
# 设置并发组为 "pages",并且不允许取消正在进行的任务
|
||||
concurrency:
|
||||
group: pages
|
||||
cancel-in-progress: false
|
||||
|
||||
# 定义工作流中的任务
|
||||
jobs:
|
||||
# 构建和部署任务
|
||||
build-and-deploy:
|
||||
# 条件判断:仅当推送的是正式版本标签(不包含预发布标识)或手动触发时执行
|
||||
if: |
|
||||
(startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-'))
|
||||
|| github.event_name == 'workflow_dispatch'
|
||||
|
||||
# 指定运行环境为最新版 Ubuntu
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# 环境配置
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
|
||||
# 步骤定义
|
||||
steps:
|
||||
# 检出代码
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# 安装 Bun 运行时
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
# 安装项目依赖
|
||||
- name: Install Dependencies
|
||||
working-directory: docs
|
||||
run: bun install
|
||||
|
||||
# 构建 VitePress 文档
|
||||
- name: Build VitePress
|
||||
working-directory: docs
|
||||
run: bun run build
|
||||
|
||||
# 生成 LLM 索引文件
|
||||
- name: Make docs LLM ready
|
||||
uses: demodrive-ai/llms-txt-action@v1
|
||||
with:
|
||||
docs_dir: docs/.vitepress/dist
|
||||
|
||||
# 上传构建产物作为 Pages 部署工件
|
||||
- name: Upload Pages Artifact
|
||||
uses: actions/upload-pages-artifact@v4
|
||||
with:
|
||||
path: docs/.vitepress/dist
|
||||
|
||||
# 将文档部署到 GitHub Pages
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
109
.github/workflows/publish.yml
vendored
109
.github/workflows/publish.yml
vendored
@ -1,8 +1,3 @@
|
||||
# 发布工作流(NuGet + GitHub Release)
|
||||
#
|
||||
# 功能:当推送标签时自动构建、打包并发布到 NuGet.org 和 GitHub Release
|
||||
# 触发条件:推送任何标签(如 v1.0.0 或 1.0.0)
|
||||
# 权限:允许写入内容、包和使用 OIDC 身份验证
|
||||
name: Publish (NuGet + GitHub Release)
|
||||
|
||||
# 触发:推送 tag 时触发(例如 v1.0.0 或 1.0.0)
|
||||
@ -28,29 +23,28 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository (at tag)
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: true
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v5
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 10.0.x
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Install unzip (for reading .nuspec from .nupkg)
|
||||
run: sudo apt-get update && sudo apt-get install -y unzip
|
||||
- name: Cache NuGet packages
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
|
||||
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
|
||||
# 从 GitHub 引用中提取标签版本
|
||||
# 提取逻辑:去除 refs/tags/ 前缀,然后去除 v/V 前缀
|
||||
# 输出:version - 处理后的版本号
|
||||
|
||||
- name: Build
|
||||
run: dotnet build -c Release --no-restore -p:DebugType=portable
|
||||
|
||||
- name: Test
|
||||
run: dotnet test --no-build -c Release --verbosity normal
|
||||
|
||||
- name: Determine tag version
|
||||
id: tag_version
|
||||
run: |
|
||||
@ -67,18 +61,7 @@ jobs:
|
||||
set -e
|
||||
echo "Packing with version=${{ steps.tag_version.outputs.version }}"
|
||||
dotnet pack -c Release -o ./packages -p:PackageVersion=${{ steps.tag_version.outputs.version }} -p:IncludeSymbols=false
|
||||
# 上传许可证合规相关的工件文件,包括通知文件、第三方许可证、SBOM文件及验证结果
|
||||
- name: Upload compliance artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: license-compliance
|
||||
path: |
|
||||
NOTICE
|
||||
THIRD_PARTY_LICENSES.md
|
||||
sbom.spdx.json
|
||||
sbom.cyclonedx.json
|
||||
sbom-spdx-validation.txt
|
||||
sbom-cyclonedx-validation.txt
|
||||
|
||||
- name: Show packages
|
||||
run: ls -la ./packages || true
|
||||
|
||||
@ -86,11 +69,8 @@ jobs:
|
||||
id: nuget_login
|
||||
uses: NuGet/login@v1
|
||||
with:
|
||||
user: ${{ secrets.NUGET_USER }}
|
||||
user: ${{ secrets.NUGET_USER }} # 推荐将用户名放 secrets
|
||||
|
||||
# 将所有生成的包推送到 nuget.org
|
||||
# 使用临时 API 密钥进行身份验证
|
||||
# 跳过重复包的上传
|
||||
- name: Push all packages to nuget.org
|
||||
env:
|
||||
NUGET_API_KEY: ${{ steps.nuget_login.outputs.NUGET_API_KEY }}
|
||||
@ -110,13 +90,7 @@ jobs:
|
||||
if [ "$pushed_any" = false ]; then
|
||||
echo "No packages found to push."
|
||||
fi
|
||||
|
||||
# 从 .nupkg 文件中提取版本信息
|
||||
# 通过解压 .nupkg(zip 格式)并读取 .nuspec 文件来获取版本
|
||||
# 输出:
|
||||
# package_file - 第一个找到的包文件路径
|
||||
# package_basename - 包文件的基本名称
|
||||
# version - 从 nuspec 中解析出的版本号
|
||||
|
||||
- name: Get Version and First Package Path
|
||||
id: get_version
|
||||
run: |
|
||||
@ -137,31 +111,38 @@ jobs:
|
||||
echo "package_basename=$BASENAME" >> $GITHUB_OUTPUT
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
# 创建 GitHub Release
|
||||
# 使用从包中提取的版本信息和当前标签创建发布
|
||||
# 发布包含描述信息和版本详情
|
||||
- name: Create GitHub Release and Upload Assets
|
||||
uses: softprops/action-gh-release@v2
|
||||
- name: Create GitHub Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
generate_release_notes: true
|
||||
name: "Release ${{ github.ref_name }}"
|
||||
body: |
|
||||
Release created by CI for tag ${{ github.ref_name }}
|
||||
Package version: ${{ steps.get_version.outputs.version }}
|
||||
|
||||
## Compliance
|
||||
- NOTICE
|
||||
- THIRD_PARTY_LICENSES
|
||||
- SPDX & CycloneDX SBOM
|
||||
tag_name: ${{ github.ref_name }}
|
||||
release_name: "Release ${{ github.ref_name }}"
|
||||
body: "Release created by CI for tag ${{ github.ref_name }} (package version ${{ steps.get_version.outputs.version }})"
|
||||
draft: false
|
||||
prerelease: false
|
||||
files: |
|
||||
./packages/*.nupkg
|
||||
NOTICE
|
||||
THIRD_PARTY_LICENSES.md
|
||||
sbom.spdx.json
|
||||
sbom.cyclonedx.json
|
||||
sbom-spdx-validation.txt
|
||||
sbom-cyclonedx-validation.txt
|
||||
|
||||
- name: Upload all .nupkg to Release (curl)
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
UPLOAD_URL_TEMPLATE: ${{ steps.create_release.outputs.upload_url }}
|
||||
run: |
|
||||
set -e
|
||||
# upload_url from create-release is like: https://uploads.github.com/repos/OWNER/REPO/releases/ID/assets{?name,label}
|
||||
# strip template part "{?name,label}"
|
||||
UPLOAD_URL="${UPLOAD_URL_TEMPLATE%\{*}"
|
||||
echo "Upload base URL: $UPLOAD_URL"
|
||||
|
||||
for package_file in ./packages/*.nupkg; do
|
||||
if [ -f "$package_file" ]; then
|
||||
basename=$(basename "$package_file")
|
||||
echo "Uploading $basename to release..."
|
||||
curl --fail -sS -X POST \
|
||||
-H "Authorization: Bearer $GITHUB_TOKEN" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
--data-binary @"$package_file" \
|
||||
"$UPLOAD_URL?name=$basename"
|
||||
echo "Uploaded $basename"
|
||||
fi
|
||||
done
|
||||
|
||||
14
.gitignore
vendored
14
.gitignore
vendored
@ -2,16 +2,4 @@ bin/
|
||||
obj/
|
||||
/packages/
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
GFramework.sln.DotSettings.user
|
||||
.idea/
|
||||
# ai
|
||||
opencode.json
|
||||
.claude/settings.local.json
|
||||
.claude/settings.json
|
||||
.omc/
|
||||
docs/.omc/
|
||||
docs/.vitepress/cache/
|
||||
local-plan/
|
||||
# tool
|
||||
.venv/
|
||||
/_ReSharper.Caches/
|
||||
@ -1,15 +0,0 @@
|
||||
# Allowlist for fake/test/demo secrets only
|
||||
# DO NOT add real credentials here
|
||||
[allowlist]
|
||||
description = "Ignore test/demo secrets"
|
||||
|
||||
paths = [
|
||||
"docs/.*",
|
||||
".*Test.*\\.json",
|
||||
".*Development.*"
|
||||
]
|
||||
|
||||
regexes = [
|
||||
"FAKE_.*_KEY",
|
||||
"TEST_.*_TOKEN"
|
||||
]
|
||||
BIN
.idea/.idea.GFramework/.idea/icon.png
generated
BIN
.idea/.idea.GFramework/.idea/icon.png
generated
Binary file not shown.
|
Before Width: | Height: | Size: 280 KiB |
@ -1,86 +0,0 @@
|
||||
# 配置文件用于设置代码质量检查工具的各项参数和规则
|
||||
# 包含全局排除目录、启用/禁用的检查器、特定语言配置等设置
|
||||
|
||||
APPLY_FIXES: none
|
||||
FAIL_ON_ERROR: false
|
||||
|
||||
# ========================
|
||||
# 全局排除目录配置
|
||||
# 定义不需要进行代码检查的目录列表
|
||||
# ========================
|
||||
EXCLUDED_DIRECTORIES:
|
||||
- bin
|
||||
- obj
|
||||
- packages
|
||||
- node_modules
|
||||
- TestResults
|
||||
- .git
|
||||
- .vs
|
||||
- .vscode
|
||||
|
||||
# ========================
|
||||
# 禁用噪音较大的检查器
|
||||
# 避免在检查过程中产生过多无关警告信息
|
||||
# ========================
|
||||
DISABLE:
|
||||
- COPYPASTE
|
||||
- SPELL
|
||||
- MARKDOWN
|
||||
|
||||
# ========================
|
||||
# 启用核心检查器列表
|
||||
# 定义需要运行的主要代码质量检查工具
|
||||
# ========================
|
||||
ENABLE_LINTERS:
|
||||
- CSHARP_DOTNET_FORMAT
|
||||
- CSHARP_ROSLYN_ANALYZERS
|
||||
- YAML
|
||||
- JSON
|
||||
- GITHUB_ACTIONS
|
||||
- REPOSITORY_GITLEAKS
|
||||
- REPOSITORY_TRUFFLEHOG
|
||||
|
||||
# ========================
|
||||
# C# 代码格式化检查配置
|
||||
# 设置 C# 代码风格检查的参数和验证级别
|
||||
# ========================
|
||||
CSHARP_DOTNET_FORMAT_ARGUMENTS:
|
||||
- "--severity"
|
||||
- "info"
|
||||
- "--verify-no-changes"
|
||||
|
||||
# ========================
|
||||
# YAML 文件检查过滤配置
|
||||
# 定义 YAML 文件的包含和排除正则表达式模式
|
||||
# ========================
|
||||
YAML_YAMLLINT_FILTER_REGEX_INCLUDE: '.*\.(ya?ml)$'
|
||||
YAML_YAMLLINT_FILTER_REGEX_EXCLUDE: '.*/.github/.*'
|
||||
|
||||
# ========================
|
||||
# JSON 文件检查过滤配置
|
||||
# 定义 JSON 文件的包含正则表达式模式
|
||||
# ========================
|
||||
JSON_JSONLINT_FILTER_REGEX_INCLUDE: '.*\.json$'
|
||||
|
||||
# ========================
|
||||
# GitHub Actions 工作流检查配置
|
||||
# 控制 GitHub Actions 文件检查的错误报告行为
|
||||
# ========================
|
||||
ACTION_ACTIONLINT_DISABLE_ERRORS: true
|
||||
|
||||
# ========================
|
||||
# 报告输出配置
|
||||
# 设置检查结果的多种报告输出格式
|
||||
# ========================
|
||||
CONSOLE_REPORTER: true
|
||||
SARIF_REPORTER: true
|
||||
GITHUB_COMMENT_REPORTER: true
|
||||
|
||||
# ========================
|
||||
# 性能优化配置
|
||||
# 控制检查过程的并行执行和时间统计选项
|
||||
# ========================
|
||||
PARALLEL: true
|
||||
SHOW_ELAPSED_TIME: true
|
||||
VALIDATE_ALL_CODEBASE: false
|
||||
|
||||
220
AGENTS.md
220
AGENTS.md
@ -1,220 +0,0 @@
|
||||
# AGENTS.md
|
||||
|
||||
This document is the single source of truth for coding behavior in this repository.
|
||||
|
||||
All AI agents and contributors must follow these rules when writing, reviewing, or modifying code in `GFramework`.
|
||||
|
||||
## Environment Capability Inventory
|
||||
|
||||
- Before choosing runtimes or CLI tools, read `@.ai/environment/tools.ai.yaml`.
|
||||
- Use `@.ai/environment/tools.raw.yaml` only when you need the full collected facts behind the AI-facing hints.
|
||||
- Prefer the project-relevant tools listed there instead of assuming every installed system tool is fair game.
|
||||
- If the real environment differs from the inventory, use the project-relevant installed tool and report the mismatch.
|
||||
|
||||
## Commenting Rules (MUST)
|
||||
|
||||
All generated or modified code MUST include clear and meaningful comments where required by the rules below.
|
||||
|
||||
### XML Documentation (Required)
|
||||
|
||||
- All public, protected, and internal types and members MUST include XML documentation comments (`///`).
|
||||
- Use `<summary>`, `<param>`, `<returns>`, `<exception>`, and `<remarks>` where applicable.
|
||||
- Comments must explain intent, contract, and usage constraints instead of restating syntax.
|
||||
- If a member participates in lifecycle, threading, registration, or disposal behavior, document that behavior
|
||||
explicitly.
|
||||
|
||||
### Inline Comments
|
||||
|
||||
- Add inline comments for:
|
||||
- Non-trivial logic
|
||||
- Concurrency or threading behavior
|
||||
- Performance-sensitive paths
|
||||
- Workarounds, compatibility constraints, or edge cases
|
||||
- Registration order, lifecycle sequencing, or generated code assumptions
|
||||
- Avoid obvious comments such as `// increment i`.
|
||||
|
||||
### Architecture-Level Comments
|
||||
|
||||
- Core framework components such as Architecture, Module, System, Context, Registry, Service Module, and Lifecycle types
|
||||
MUST include high-level explanations of:
|
||||
- Responsibilities
|
||||
- Lifecycle
|
||||
- Interaction with other components
|
||||
- Why the abstraction exists
|
||||
- When to use it instead of alternatives
|
||||
|
||||
### Source Generator Comments
|
||||
|
||||
- Generated logic and generator pipelines MUST explain:
|
||||
- What is generated
|
||||
- Why it is generated
|
||||
- The semantic assumptions the generator relies on
|
||||
- Any diagnostics or fallback behavior
|
||||
|
||||
### Complex Logic Requirement
|
||||
|
||||
- Methods with non-trivial logic MUST document:
|
||||
- The core idea
|
||||
- Key decisions
|
||||
- Edge case handling, if any
|
||||
|
||||
### Quality Rules
|
||||
|
||||
- Comments MUST NOT be trivial, redundant, or misleading.
|
||||
- Prefer explaining `why` and `when`, not just `what`.
|
||||
- Code should remain understandable without requiring external context.
|
||||
- Prefer slightly more explanation over too little for framework code.
|
||||
|
||||
### Enforcement
|
||||
|
||||
- Missing required documentation is a coding standards violation.
|
||||
- Code that does not meet the documentation rules is considered incomplete.
|
||||
|
||||
## Code Style
|
||||
|
||||
### Language and Project Settings
|
||||
|
||||
- Follow the repository defaults:
|
||||
- `ImplicitUsings` disabled
|
||||
- `Nullable` enabled
|
||||
- `GenerateDocumentationFile` enabled for shipped libraries
|
||||
- `LangVersion` is generally `preview` in the main libraries and abstractions
|
||||
- Do not rely on implicit imports. Declare every required `using` explicitly.
|
||||
- Write null-safe code that respects nullable annotations instead of suppressing warnings by default.
|
||||
|
||||
### Naming and Structure
|
||||
|
||||
- Use the namespace pattern `GFramework.{Module}.{Feature}` with PascalCase segments.
|
||||
- Follow standard C# naming:
|
||||
- Types, methods, properties, events, and constants: PascalCase
|
||||
- Interfaces: `I` prefix
|
||||
- Parameters and locals: camelCase
|
||||
- Private fields: `_camelCase`
|
||||
- Keep abstractions projects free of implementation details and engine-specific dependencies.
|
||||
- Preserve existing module boundaries. Do not introduce new cross-module dependencies without clear architectural need.
|
||||
|
||||
### Formatting
|
||||
|
||||
- Use 4 spaces for indentation. Do not use tabs.
|
||||
- Use Allman braces.
|
||||
- Keep `using` directives at the top of the file and sort them consistently.
|
||||
- Separate logical blocks with blank lines when it improves readability.
|
||||
- Prefer one primary type per file unless the surrounding project already uses a different local pattern.
|
||||
- Keep line length readable. Around 120 characters is the preferred upper bound.
|
||||
|
||||
### C# Conventions
|
||||
|
||||
- Prefer explicit, readable code over clever shorthand in framework internals.
|
||||
- Match existing async patterns and naming conventions (`Async` suffix for asynchronous methods).
|
||||
- Avoid hidden side effects in property getters, constructors, and registration helpers.
|
||||
- Preserve deterministic behavior in registries, lifecycle orchestration, and generated outputs.
|
||||
- When adding analyzers or suppressions, keep them minimal and justify them in code comments if the reason is not
|
||||
obvious.
|
||||
|
||||
### Analyzer and Validation Expectations
|
||||
|
||||
- The repository uses `Meziantou.Analyzer`; treat analyzer feedback as part of the coding standard.
|
||||
- Naming must remain compatible with `scripts/validate-csharp-naming.sh`.
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
### Required Coverage
|
||||
|
||||
- Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test
|
||||
is not practical.
|
||||
- Public API changes must be covered by unit or integration tests.
|
||||
- Regression fixes should include a test that fails before the fix and passes after it.
|
||||
|
||||
### Test Organization
|
||||
|
||||
- Mirror the source structure in test projects whenever practical.
|
||||
- Reuse existing architecture test infrastructure when relevant:
|
||||
- `ArchitectureTestsBase<T>`
|
||||
- `SyncTestArchitecture`
|
||||
- `AsyncTestArchitecture`
|
||||
- Keep tests focused on observable behavior, not implementation trivia.
|
||||
|
||||
### Source Generator Tests
|
||||
|
||||
- Source generator changes MUST be covered by generator tests.
|
||||
- Preserve snapshot-based verification patterns already used in the repository.
|
||||
- When generator behavior changes intentionally, update snapshots together with the implementation.
|
||||
|
||||
### Validation Commands
|
||||
|
||||
Use the smallest command set that proves the change, then expand if the change is cross-cutting.
|
||||
|
||||
```bash
|
||||
# Build the full solution
|
||||
dotnet build GFramework.sln -c Release
|
||||
|
||||
# Run all tests
|
||||
dotnet test GFramework.sln -c Release
|
||||
|
||||
# Run a single test project
|
||||
dotnet test GFramework.Core.Tests -c Release
|
||||
dotnet test GFramework.Game.Tests -c Release
|
||||
dotnet test GFramework.SourceGenerators.Tests -c Release
|
||||
dotnet test GFramework.Ecs.Arch.Tests -c Release
|
||||
|
||||
# Run a single NUnit test or test group
|
||||
dotnet test GFramework.Core.Tests -c Release --filter "FullyQualifiedName~CommandExecutorTests.Execute"
|
||||
|
||||
# Validate naming rules used by CI
|
||||
bash scripts/validate-csharp-naming.sh
|
||||
```
|
||||
|
||||
### Test Execution Expectations
|
||||
|
||||
- Run targeted tests for the code you changed whenever possible.
|
||||
- Run broader solution-level validation for changes that touch shared abstractions, lifecycle behavior, source
|
||||
generators, or dependency wiring.
|
||||
- Do not claim completion if required tests were skipped; state what was not run and why.
|
||||
|
||||
## Security Rules
|
||||
|
||||
- Validate external or user-controlled input before it reaches file system, serialization, reflection, code generation,
|
||||
or process boundaries.
|
||||
- Do not build command strings, file paths, type names, or generated code from untrusted input without strict validation
|
||||
or allow-listing.
|
||||
- Avoid logging secrets, tokens, credentials, or machine-specific sensitive data.
|
||||
- Keep source generators deterministic and free of hidden environment or network dependencies.
|
||||
- Prefer least-privilege behavior for file, process, and environment access.
|
||||
- Do not introduce unsafe deserialization, broad reflection-based activation, or dynamic code execution unless it is
|
||||
explicitly required and tightly constrained.
|
||||
- When adding caching, pooling, or shared mutable state, document thread-safety assumptions and failure modes.
|
||||
- Minimize new package dependencies. Add them only when necessary and keep scope narrow.
|
||||
|
||||
## Documentation Rules
|
||||
|
||||
### Code Documentation
|
||||
|
||||
- Any change to public API, lifecycle semantics, module behavior, or extension points MUST update the related XML docs.
|
||||
- If a framework abstraction changes meaning or intended usage, update the explanatory comments in code as part of the
|
||||
same change.
|
||||
|
||||
### Repository Documentation
|
||||
|
||||
- Update the relevant `README.md` or `docs/` page when behavior, setup steps, architecture guidance, or user-facing
|
||||
examples change.
|
||||
- The main documentation site lives under `docs/`, with Chinese content under `docs/zh-CN/`.
|
||||
- Keep code samples, package names, and command examples aligned with the current repository state.
|
||||
- Prefer documenting behavior and design intent, not only API surface.
|
||||
|
||||
### Documentation Preview
|
||||
|
||||
When documentation changes need local preview, use:
|
||||
|
||||
```bash
|
||||
cd docs && bun install && bun run dev
|
||||
```
|
||||
|
||||
## Review Standard
|
||||
|
||||
Before considering work complete, confirm:
|
||||
|
||||
- Required comments and XML docs are present
|
||||
- Code follows repository style and naming rules
|
||||
- Relevant tests were added or updated
|
||||
- Sensitive or unsafe behavior was not introduced
|
||||
- User-facing documentation is updated when needed
|
||||
134
CLAUDE.md
134
CLAUDE.md
@ -1,134 +0,0 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides project understanding for AI agents working in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
GFramework 是面向游戏开发的模块化 C# 框架,核心能力与引擎解耦。项目灵感参考 QFramework,并在模块边界、工程组织和可扩展性方面持续重构。
|
||||
|
||||
## AI Agent Instructions
|
||||
|
||||
All coding rules are defined in:
|
||||
|
||||
@AGENTS.md
|
||||
|
||||
Follow them strictly.
|
||||
|
||||
## Module Dependency Graph
|
||||
|
||||
```text
|
||||
GFramework (meta package) ─→ Core + Game
|
||||
GFramework.Core ─→ Core.Abstractions
|
||||
GFramework.Game ─→ Game.Abstractions, Core, Core.Abstractions
|
||||
GFramework.Godot ─→ Core, Game, Core.Abstractions, Game.Abstractions
|
||||
GFramework.Ecs.Arch ─→ Ecs.Arch.Abstractions, Core, Core.Abstractions
|
||||
GFramework.SourceGenerators ─→ SourceGenerators.Common, SourceGenerators.Abstractions
|
||||
```
|
||||
|
||||
- **Abstractions projects** (`netstandard2.1`): 只包含接口和契约定义,不承载运行时实现逻辑。
|
||||
- **Core / Game / Ecs.Arch** (`net8.0;net9.0;net10.0`): 平台无关的核心实现层。
|
||||
- **Godot**: Godot 引擎集成层,负责与节点、场景和引擎生命周期对接。
|
||||
- **SourceGenerators** (`netstandard2.1`): Roslyn 增量源码生成器及其公共基础设施。
|
||||
|
||||
## Architecture Pattern
|
||||
|
||||
框架核心采用 `Architecture / Model / System / Utility` 四层结构:
|
||||
|
||||
- **IArchitecture**: 顶层容器,负责生命周期管理、组件注册、模块安装和统一服务访问。
|
||||
- **IContextAware**: 统一上下文访问接口,组件通过 `SetContext(IArchitectureContext)` 获取架构上下文。
|
||||
- **IModel**: 数据与状态层,负责长期状态和业务数据建模。
|
||||
- **ISystem**: 业务逻辑层,负责命令执行、流程编排和规则落地。
|
||||
- **IUtility**: 通用无状态工具层,供其他层复用。
|
||||
|
||||
关键实现位于 `GFramework.Core/Architectures/Architecture.cs`,其职责是作为总协调器串联生命周期、组件注册和模块系统。
|
||||
|
||||
## Architecture Details
|
||||
|
||||
### Lifecycle
|
||||
|
||||
Architecture 负责统一生命周期编排,核心阶段包括:
|
||||
|
||||
- `Init`
|
||||
- `Ready`
|
||||
- `Destroy`
|
||||
|
||||
在实现层中,生命周期被拆分为更细粒度的初始化与销毁阶段,用于保证 Utility、Model、System、服务模块和钩子的顺序一致性。
|
||||
|
||||
### Component Coordination
|
||||
|
||||
框架通过独立组件协作完成架构编排:
|
||||
|
||||
- `ArchitectureLifecycle`: 管理生命周期阶段、阶段转换和生命周期钩子。
|
||||
- `ArchitectureComponentRegistry`: 管理 Model、System、Utility 的注册与解析。
|
||||
- `ArchitectureModules`: 管理模块安装、服务模块接入和扩展点注册。
|
||||
|
||||
这组拆分的目标是降低单个核心类的职责密度,同时保持对外 API 稳定。
|
||||
|
||||
### Context Propagation
|
||||
|
||||
`IArchitectureContext` 和相关 Provider 类型负责在组件之间传播上下文能力,使 Model、System
|
||||
和外部扩展都能通过统一入口访问架构服务,而不直接耦合具体实现细节。
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### CQRS
|
||||
|
||||
命令与查询分离,支持同步与异步执行。Mediator 模式通过源码生成器集成,以减少模板代码并保持调用路径清晰。
|
||||
|
||||
### EventBus
|
||||
|
||||
类型安全事件总线支持事件发布、订阅、优先级、过滤器和弱引用订阅。它是模块之间松耦合通信的核心基础设施之一。
|
||||
|
||||
### BindableProperty
|
||||
|
||||
响应式属性模型通过值变化通知驱动界面或业务层更新,适合表达轻量级状态同步。
|
||||
|
||||
### Coroutine
|
||||
|
||||
帧驱动协程系统基于 `IYieldInstruction` 和调度器抽象,支持等待时间、事件和任务完成等常见模式。
|
||||
|
||||
### IoC
|
||||
|
||||
依赖注入通过 `MicrosoftDiContainer` 对 `Microsoft.Extensions.DependencyInjection` 进行封装,用于统一组件注册和服务解析体验。
|
||||
|
||||
### Service Modules
|
||||
|
||||
`IServiceModule` 模式用于向 Architecture 注册内置服务,例如 EventBus、CommandExecutor、QueryExecutor 等。这一模式承担“基础设施能力装配”的职责。
|
||||
|
||||
## Source Generators
|
||||
|
||||
当前仓库包含多类 Roslyn 增量源码生成器:
|
||||
|
||||
- `LoggerGenerator` (`[Log]`): 自动生成日志字段和日志辅助方法。
|
||||
- `PriorityGenerator` (`[Priority]`): 生成优先级比较相关实现。
|
||||
- `EnumExtensionsGenerator` (`[GenerateEnumExtensions]`): 生成枚举扩展能力。
|
||||
- `ContextAwareGenerator` (`[ContextAware]`): 自动实现 `IContextAware` 相关样板逻辑。
|
||||
|
||||
这些生成器的目标是减少重复代码,同时保持框架层 API 的一致性与可维护性。
|
||||
|
||||
## Module Structure
|
||||
|
||||
仓库以“抽象层 + 实现层 + 集成层 + 生成器层”的方式组织:
|
||||
|
||||
- `GFramework.Core.Abstractions` / `GFramework.Game.Abstractions`: 约束接口和公共契约。
|
||||
- `GFramework.Core` / `GFramework.Game`: 提供平台无关实现。
|
||||
- `GFramework.Godot`: 提供与 Godot 运行时集成的适配实现。
|
||||
- `GFramework.Ecs.Arch`: 提供 ECS Architecture 相关扩展。
|
||||
- `GFramework.SourceGenerators` 及相关 Abstractions/Common: 提供代码生成能力。
|
||||
|
||||
这种结构的核心设计目标是让抽象稳定、实现可替换、引擎集成隔离、生成器能力可独立演进。
|
||||
|
||||
## Documentation Structure
|
||||
|
||||
项目文档位于 `docs/`,中文内容位于 `docs/zh-CN/`。文档内容覆盖:
|
||||
|
||||
- 入门与安装
|
||||
- Core / Game / Godot / ECS 各模块能力
|
||||
- Source Generator 使用说明
|
||||
- 教程、最佳实践与故障排查
|
||||
|
||||
阅读顺序通常建议先看根目录 `README.md` 和各子模块 `README.md`,再进入 `docs/` 查阅专题说明。
|
||||
|
||||
## Design Intent
|
||||
|
||||
GFramework 的设计重点不是把所有能力堆进单一核心类,而是通过清晰的模块边界、可组合的服务注册方式、稳定的抽象契约以及适度自动化的源码生成,构建一个适合长期演进的游戏开发基础框架。
|
||||
@ -1,42 +0,0 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构模块注册表 - 用于外部模块的自动注册
|
||||
/// </summary>
|
||||
public static class ArchitectureModuleRegistry
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, Func<IServiceModule>> Factories = new(StringComparer.Ordinal);
|
||||
|
||||
/// <summary>
|
||||
/// 注册模块工厂(幂等操作,相同模块名只会注册一次)
|
||||
/// </summary>
|
||||
/// <param name="factory">模块工厂函数</param>
|
||||
public static void Register(Func<IServiceModule> factory)
|
||||
{
|
||||
// 创建临时实例以获取模块名(用于幂等性检查)
|
||||
var tempModule = factory();
|
||||
var moduleName = tempModule.ModuleName;
|
||||
|
||||
// 幂等注册:相同模块名只注册一次
|
||||
Factories.TryAdd(moduleName, factory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建所有已注册的模块实例
|
||||
/// </summary>
|
||||
/// <returns>模块实例集合</returns>
|
||||
public static IEnumerable<IServiceModule> CreateModules()
|
||||
{
|
||||
return Factories.Values.Select(f => f());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空注册表(主要用于测试)
|
||||
/// </summary>
|
||||
public static void Clear()
|
||||
{
|
||||
Factories.Clear();
|
||||
}
|
||||
}
|
||||
@ -1,102 +0,0 @@
|
||||
using GFramework.Core.Abstractions.Lifecycle;
|
||||
using GFramework.Core.Abstractions.Model;
|
||||
using GFramework.Core.Abstractions.Systems;
|
||||
using GFramework.Core.Abstractions.Utility;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构接口,专注于生命周期管理,包括系统、模型、工具的注册和获取
|
||||
/// 业务操作通过 ArchitectureRuntime 提供
|
||||
/// </summary>
|
||||
public interface IArchitecture : IAsyncInitializable, IAsyncDestroyable, IInitializable, IDestroyable
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取架构上下文
|
||||
/// </summary>
|
||||
IArchitectureContext Context { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置用于配置服务集合的委托
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// 一个可为空的委托,用于配置IServiceCollection实例
|
||||
/// </value>
|
||||
Action<IServiceCollection>? Configurator { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册系统实例到架构中
|
||||
/// </summary>
|
||||
/// <typeparam name="T">系统类型,必须实现ISystem接口</typeparam>
|
||||
/// <param name="system">要注册的系统实例</param>
|
||||
/// <returns>注册的系统实例</returns>
|
||||
T RegisterSystem<T>(T system) where T : ISystem;
|
||||
|
||||
/// <summary>
|
||||
/// 注册系统实例到架构中
|
||||
/// </summary>
|
||||
/// <typeparam name="T">系统类型,必须实现ISystem接口</typeparam>
|
||||
/// <param name="onCreated">系统实例创建后的回调函数,可为null</param>
|
||||
void RegisterSystem<T>(Action<T>? onCreated = null) where T : class, ISystem;
|
||||
|
||||
/// <summary>
|
||||
/// 注册模型实例到架构中
|
||||
/// </summary>
|
||||
/// <typeparam name="T">模型类型,必须实现IModel接口</typeparam>
|
||||
/// <param name="model">要注册的模型实例</param>
|
||||
/// <returns>注册的模型实例</returns>
|
||||
T RegisterModel<T>(T model) where T : IModel;
|
||||
|
||||
/// <summary>
|
||||
/// 注册模型实例到架构中
|
||||
/// </summary>
|
||||
/// <typeparam name="T">模型类型,必须实现IModel接口</typeparam>
|
||||
/// <param name="onCreated">模型实例创建后的回调函数,可为null</param>
|
||||
void RegisterModel<T>(Action<T>? onCreated = null) where T : class, IModel;
|
||||
|
||||
/// <summary>
|
||||
/// 注册工具实例到架构中
|
||||
/// </summary>
|
||||
/// <typeparam name="T">工具类型,必须实现IUtility接口</typeparam>
|
||||
/// <param name="utility">要注册的工具实例</param>
|
||||
/// <returns>注册的工具实例</returns>
|
||||
T RegisterUtility<T>(T utility) where T : IUtility;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 注册工具类型并可选地指定创建回调
|
||||
/// 当工具实例被创建时会调用指定的回调函数
|
||||
/// </summary>
|
||||
/// <typeparam name="T">工具类型,必须是引用类型且实现IUtility接口</typeparam>
|
||||
/// <param name="onCreated">工具实例创建后的回调函数,可为null</param>
|
||||
void RegisterUtility<T>(Action<T>? onCreated = null) where T : class, IUtility;
|
||||
|
||||
/// <summary>
|
||||
/// 注册中介行为管道
|
||||
/// 用于配置Mediator框架的行为拦截和处理逻辑
|
||||
/// </summary>
|
||||
/// <typeparam name="TBehavior">行为类型,必须是引用类型</typeparam>
|
||||
void RegisterMediatorBehavior<TBehavior>()
|
||||
where TBehavior : class;
|
||||
|
||||
/// <summary>
|
||||
/// 安装架构模块
|
||||
/// </summary>
|
||||
/// <param name="module">要安装的模块</param>
|
||||
/// <returns>安装的模块实例</returns>
|
||||
IArchitectureModule InstallModule(IArchitectureModule module);
|
||||
|
||||
/// <summary>
|
||||
/// 注册生命周期钩子
|
||||
/// </summary>
|
||||
/// <param name="hook">生命周期钩子实例</param>
|
||||
/// <returns>注册的钩子实例</returns>
|
||||
IArchitectureLifecycleHook RegisterLifecycleHook(IArchitectureLifecycleHook hook);
|
||||
|
||||
/// <summary>
|
||||
/// 等待直到架构准备就绪的异步操作
|
||||
/// </summary>
|
||||
/// <returns>表示异步等待操作的任务</returns>
|
||||
Task WaitUntilReadyAsync();
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
using GFramework.Core.Abstractions.Properties;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 定义架构配置的接口,提供日志工厂、日志级别和架构选项的配置功能
|
||||
/// </summary>
|
||||
public interface IArchitectureConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置日志选项,包含日志相关的配置参数
|
||||
/// </summary>
|
||||
LoggerProperties LoggerProperties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置架构选项,包含架构相关的配置参数
|
||||
/// </summary>
|
||||
ArchitectureProperties ArchitectureProperties { get; set; }
|
||||
}
|
||||
@ -1,268 +0,0 @@
|
||||
using GFramework.Core.Abstractions.Command;
|
||||
using GFramework.Core.Abstractions.Environment;
|
||||
using GFramework.Core.Abstractions.Events;
|
||||
using GFramework.Core.Abstractions.Model;
|
||||
using GFramework.Core.Abstractions.Query;
|
||||
using GFramework.Core.Abstractions.Systems;
|
||||
using GFramework.Core.Abstractions.Utility;
|
||||
using Mediator;
|
||||
using ICommand = GFramework.Core.Abstractions.Command.ICommand;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构上下文接口,提供对系统、模型、工具类的访问以及命令、查询、事件的发送和注册功能
|
||||
/// </summary>
|
||||
public interface IArchitectureContext
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取指定类型的服务实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TService">服务类型</typeparam>
|
||||
/// <returns>服务实例,如果不存在则抛出异常</returns>
|
||||
TService GetService<TService>() where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有服务实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TService">服务类型</typeparam>
|
||||
/// <returns>所有符合条件的服务实例列表</returns>
|
||||
IReadOnlyList<TService> GetServices<TService>() where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的系统实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TSystem">系统类型,必须继承自ISystem接口</typeparam>
|
||||
/// <returns>系统实例,如果不存在则抛出异常</returns>
|
||||
TSystem GetSystem<TSystem>() where TSystem : class, ISystem;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有系统实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TSystem">系统类型,必须继承自ISystem接口</typeparam>
|
||||
/// <returns>所有符合条件的系统实例列表</returns>
|
||||
IReadOnlyList<TSystem> GetSystems<TSystem>() where TSystem : class, ISystem;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的模型实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">模型类型,必须继承自IModel接口</typeparam>
|
||||
/// <returns>模型实例,如果不存在则抛出异常</returns>
|
||||
TModel GetModel<TModel>() where TModel : class, IModel;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有模型实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">模型类型,必须继承自IModel接口</typeparam>
|
||||
/// <returns>所有符合条件的模型实例列表</returns>
|
||||
IReadOnlyList<TModel> GetModels<TModel>() where TModel : class, IModel;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的工具类实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TUtility">工具类类型,必须继承自IUtility接口</typeparam>
|
||||
/// <returns>工具类实例,如果不存在则抛出异常</returns>
|
||||
TUtility GetUtility<TUtility>() where TUtility : class, IUtility;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有工具类实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TUtility">工具类类型,必须继承自IUtility接口</typeparam>
|
||||
/// <returns>所有符合条件的工具类实例列表</returns>
|
||||
IReadOnlyList<TUtility> GetUtilities<TUtility>() where TUtility : class, IUtility;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有服务实例,并按优先级排序
|
||||
/// 实现 IPrioritized 接口的服务将按优先级排序(数值越小优先级越高)
|
||||
/// </summary>
|
||||
/// <typeparam name="TService">服务类型</typeparam>
|
||||
/// <returns>按优先级排序后的服务实例列表</returns>
|
||||
IReadOnlyList<TService> GetServicesByPriority<TService>() where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有系统实例,并按优先级排序
|
||||
/// 实现 IPrioritized 接口的系统将按优先级排序(数值越小优先级越高)
|
||||
/// </summary>
|
||||
/// <typeparam name="TSystem">系统类型,必须继承自ISystem接口</typeparam>
|
||||
/// <returns>按优先级排序后的系统实例列表</returns>
|
||||
IReadOnlyList<TSystem> GetSystemsByPriority<TSystem>() where TSystem : class, ISystem;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有模型实例,并按优先级排序
|
||||
/// 实现 IPrioritized 接口的模型将按优先级排序(数值越小优先级越高)
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">模型类型,必须继承自IModel接口</typeparam>
|
||||
/// <returns>按优先级排序后的模型实例列表</returns>
|
||||
IReadOnlyList<TModel> GetModelsByPriority<TModel>() where TModel : class, IModel;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有工具类实例,并按优先级排序
|
||||
/// 实现 IPrioritized 接口的工具将按优先级排序(数值越小优先级越高)
|
||||
/// </summary>
|
||||
/// <typeparam name="TUtility">工具类类型,必须继承自IUtility接口</typeparam>
|
||||
/// <returns>按优先级排序后的工具类实例列表</returns>
|
||||
IReadOnlyList<TUtility> GetUtilitiesByPriority<TUtility>() where TUtility : class, IUtility;
|
||||
|
||||
/// <summary>
|
||||
/// 发送一个命令
|
||||
/// </summary>
|
||||
/// <param name="command">要发送的命令</param>
|
||||
void SendCommand(ICommand command);
|
||||
|
||||
/// <summary>
|
||||
/// 发送一个带返回值的命令
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">命令执行结果类型</typeparam>
|
||||
/// <param name="command">要发送的命令</param>
|
||||
/// <returns>命令执行结果</returns>
|
||||
TResult SendCommand<TResult>(Command.ICommand<TResult> command);
|
||||
|
||||
/// <summary>
|
||||
/// [Mediator] 发送命令的同步版本(不推荐,仅用于兼容性)
|
||||
/// </summary>
|
||||
/// <typeparam name="TResponse">命令响应类型</typeparam>
|
||||
/// <param name="command">要发送的命令对象</param>
|
||||
/// <returns>命令执行结果</returns>
|
||||
TResponse SendCommand<TResponse>(Mediator.ICommand<TResponse> command);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 发送并异步执行一个命令
|
||||
/// </summary>
|
||||
/// <param name="command">要发送的命令</param>
|
||||
Task SendCommandAsync(IAsyncCommand command);
|
||||
|
||||
/// <summary>
|
||||
/// [Mediator] 异步发送命令并返回结果
|
||||
/// 通过Mediator模式发送命令请求,支持取消操作
|
||||
/// </summary>
|
||||
/// <typeparam name="TResponse">命令响应类型</typeparam>
|
||||
/// <param name="command">要发送的命令对象</param>
|
||||
/// <param name="cancellationToken">取消令牌,用于取消操作</param>
|
||||
/// <returns>包含命令执行结果的ValueTask</returns>
|
||||
ValueTask<TResponse> SendCommandAsync<TResponse>(Mediator.ICommand<TResponse> command,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 发送并异步执行一个带返回值的命令
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">命令执行结果类型</typeparam>
|
||||
/// <param name="command">要发送的命令</param>
|
||||
/// <returns>命令执行结果</returns>
|
||||
Task<TResult> SendCommandAsync<TResult>(IAsyncCommand<TResult> command);
|
||||
|
||||
/// <summary>
|
||||
/// 发送一个查询请求
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">查询结果类型</typeparam>
|
||||
/// <param name="query">要发送的查询</param>
|
||||
/// <returns>查询结果</returns>
|
||||
TResult SendQuery<TResult>(Query.IQuery<TResult> query);
|
||||
|
||||
/// <summary>
|
||||
/// [Mediator] 发送查询的同步版本(不推荐,仅用于兼容性)
|
||||
/// </summary>
|
||||
/// <typeparam name="TResponse">查询响应类型</typeparam>
|
||||
/// <param name="query">要发送的查询对象</param>
|
||||
/// <returns>查询结果</returns>
|
||||
TResponse SendQuery<TResponse>(Mediator.IQuery<TResponse> query);
|
||||
|
||||
/// <summary>
|
||||
/// 异步发送一个查询请求
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">查询结果类型</typeparam>
|
||||
/// <param name="query">要发送的异步查询</param>
|
||||
/// <returns>查询结果</returns>
|
||||
Task<TResult> SendQueryAsync<TResult>(IAsyncQuery<TResult> query);
|
||||
|
||||
/// <summary>
|
||||
/// [Mediator] 异步发送查询并返回结果
|
||||
/// 通过Mediator模式发送查询请求,支持取消操作
|
||||
/// </summary>
|
||||
/// <typeparam name="TResponse">查询响应类型</typeparam>
|
||||
/// <param name="query">要发送的查询对象</param>
|
||||
/// <param name="cancellationToken">取消令牌,用于取消操作</param>
|
||||
/// <returns>包含查询结果的ValueTask</returns>
|
||||
ValueTask<TResponse> SendQueryAsync<TResponse>(Mediator.IQuery<TResponse> query,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 发送一个事件
|
||||
/// </summary>
|
||||
/// <typeparam name="TEvent">事件类型,必须具有无参构造函数</typeparam>
|
||||
void SendEvent<TEvent>() where TEvent : new();
|
||||
|
||||
/// <summary>
|
||||
/// 发送一个带参数的事件
|
||||
/// </summary>
|
||||
/// <typeparam name="TEvent">事件类型</typeparam>
|
||||
/// <param name="e">事件参数</param>
|
||||
void SendEvent<TEvent>(TEvent e) where TEvent : class;
|
||||
|
||||
/// <summary>
|
||||
/// 注册事件处理器
|
||||
/// </summary>
|
||||
/// <typeparam name="TEvent">事件类型</typeparam>
|
||||
/// <param name="handler">事件处理委托</param>
|
||||
/// <returns>事件注销接口</returns>
|
||||
IUnRegister RegisterEvent<TEvent>(Action<TEvent> handler);
|
||||
|
||||
/// <summary>
|
||||
/// 取消注册事件监听器
|
||||
/// </summary>
|
||||
/// <typeparam name="TEvent">事件类型</typeparam>
|
||||
/// <param name="onEvent">要取消注册的事件回调方法</param>
|
||||
void UnRegisterEvent<TEvent>(Action<TEvent> onEvent);
|
||||
|
||||
/// <summary>
|
||||
/// 发送请求(统一处理 Command/Query)
|
||||
/// </summary>
|
||||
ValueTask<TResponse> SendRequestAsync<TResponse>(
|
||||
IRequest<TResponse> request,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 发送请求(同步版本,不推荐)
|
||||
/// </summary>
|
||||
TResponse SendRequest<TResponse>(IRequest<TResponse> request);
|
||||
|
||||
/// <summary>
|
||||
/// 发布通知(一对多事件)
|
||||
/// </summary>
|
||||
ValueTask PublishAsync<TNotification>(
|
||||
TNotification notification,
|
||||
CancellationToken cancellationToken = default)
|
||||
where TNotification : INotification;
|
||||
|
||||
/// <summary>
|
||||
/// 创建流式请求(用于大数据集)
|
||||
/// </summary>
|
||||
IAsyncEnumerable<TResponse> CreateStream<TResponse>(
|
||||
IStreamRequest<TResponse> request,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
// === 便捷扩展方法 ===
|
||||
|
||||
/// <summary>
|
||||
/// 发送命令(无返回值)
|
||||
/// </summary>
|
||||
ValueTask SendAsync<TCommand>(
|
||||
TCommand command,
|
||||
CancellationToken cancellationToken = default)
|
||||
where TCommand : IRequest<Unit>;
|
||||
|
||||
/// <summary>
|
||||
/// 发送命令(有返回值)
|
||||
/// </summary>
|
||||
ValueTask<TResponse> SendAsync<TResponse>(
|
||||
IRequest<TResponse> command,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取环境对象
|
||||
/// </summary>
|
||||
/// <returns>环境对象实例</returns>
|
||||
IEnvironment GetEnvironment();
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构上下文提供者接口,用于解耦上下文获取逻辑
|
||||
/// </summary>
|
||||
public interface IArchitectureContextProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前的架构上下文
|
||||
/// </summary>
|
||||
/// <returns>架构上下文实例</returns>
|
||||
IArchitectureContext GetContext();
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取指定类型的架构上下文
|
||||
/// </summary>
|
||||
/// <typeparam name="T">架构上下文类型</typeparam>
|
||||
/// <param name="context">输出的上下文实例</param>
|
||||
/// <returns>如果成功获取则返回true,否则返回false</returns>
|
||||
bool TryGetContext<T>(out T? context) where T : class, IArchitectureContext;
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
using GFramework.Core.Abstractions.Enums;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构生命周期钩子接口,用于在架构的不同生命周期阶段执行自定义逻辑。
|
||||
/// 实现此接口的类可以监听架构阶段变化并访问相关的架构实例。
|
||||
/// </summary>
|
||||
public interface IArchitectureLifecycleHook
|
||||
{
|
||||
/// <summary>
|
||||
/// 当架构进入指定阶段时触发的回调方法。
|
||||
/// </summary>
|
||||
/// <param name="phase">当前的架构阶段</param>
|
||||
/// <param name="architecture">相关的架构实例</param>
|
||||
void OnPhase(ArchitecturePhase phase, IArchitecture architecture);
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构模块接口,继承自架构生命周期接口。
|
||||
/// 定义了模块安装到架构中的标准方法。
|
||||
/// </summary>
|
||||
public interface IArchitectureModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 将当前模块安装到指定的架构中。
|
||||
/// </summary>
|
||||
/// <param name="architecture">要安装模块的目标架构实例。</param>
|
||||
void Install(IArchitecture architecture);
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
using GFramework.Core.Abstractions.Enums;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构阶段监听器接口,用于监听和响应架构生命周期中的不同阶段变化。
|
||||
/// 实现此接口的类可以在架构进入特定阶段时执行相应的逻辑处理。
|
||||
/// </summary>
|
||||
public interface IArchitecturePhaseListener
|
||||
{
|
||||
/// <summary>
|
||||
/// 当架构进入指定阶段时触发的回调方法。
|
||||
/// </summary>
|
||||
/// <param name="phase">架构阶段枚举值,表示当前所处的架构阶段</param>
|
||||
void OnArchitecturePhase(ArchitecturePhase phase);
|
||||
}
|
||||
@ -1,49 +0,0 @@
|
||||
using GFramework.Core.Abstractions.Command;
|
||||
using GFramework.Core.Abstractions.Events;
|
||||
using GFramework.Core.Abstractions.Ioc;
|
||||
using GFramework.Core.Abstractions.Query;
|
||||
using GFramework.Core.Abstractions.Rule;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构服务接口,定义了框架核心架构所需的服务组件
|
||||
/// </summary>
|
||||
public interface IArchitectureServices : IContextAware
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取依赖注入容器
|
||||
/// </summary>
|
||||
/// <returns>IIocContainer类型的依赖注入容器实例</returns>
|
||||
IIocContainer Container { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取类型事件系统
|
||||
/// </summary>
|
||||
/// <returns>ITypeEventSystem类型的事件系统实例</returns>
|
||||
IEventBus EventBus { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取命令执行器
|
||||
/// </summary>
|
||||
/// <returns>ICommandExecutor类型的命令执行器实例</returns>
|
||||
ICommandExecutor CommandExecutor { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取查询执行器
|
||||
/// </summary>
|
||||
/// <returns>IQueryExecutor类型的查询执行器实例</returns>
|
||||
IQueryExecutor QueryExecutor { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取异步查询执行器
|
||||
/// </summary>
|
||||
/// <returns>IAsyncQueryExecutor类型的异步查询执行器实例</returns>
|
||||
IAsyncQueryExecutor AsyncQueryExecutor { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取服务模块管理器
|
||||
/// </summary>
|
||||
/// <returns>IServiceModuleManager类型的服务模块管理器实例</returns>
|
||||
IServiceModuleManager ModuleManager { get; }
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
using GFramework.Core.Abstractions.Ioc;
|
||||
using GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 服务模块接口,定义了服务模块的基本契约。
|
||||
/// 所有服务模块必须实现此接口,以支持注册、初始化和异步销毁功能。
|
||||
/// </summary>
|
||||
public interface IServiceModule : IInitializable, IAsyncDestroyable
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取模块的唯一名称。
|
||||
/// </summary>
|
||||
string ModuleName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取模块的优先级,数值越小优先级越高。
|
||||
/// 用于控制模块的注册和初始化顺序。
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取模块的启用状态。
|
||||
/// 返回 true 表示模块已启用,false 表示模块被禁用。
|
||||
/// </summary>
|
||||
bool IsEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册模块提供的服务到依赖注入容器中。
|
||||
/// </summary>
|
||||
/// <param name="container">依赖注入容器实例,用于注册服务。</param>
|
||||
void Register(IIocContainer container);
|
||||
}
|
||||
@ -1,40 +0,0 @@
|
||||
using GFramework.Core.Abstractions.Ioc;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 服务模块管理器接口,用于管理架构中的服务模块。
|
||||
/// </summary>
|
||||
public interface IServiceModuleManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 注册一个服务模块。
|
||||
/// </summary>
|
||||
/// <param name="module">要注册的服务模块实例。</param>
|
||||
void RegisterModule(IServiceModule module);
|
||||
|
||||
/// <summary>
|
||||
/// 注册内置的服务模块。
|
||||
/// </summary>
|
||||
/// <param name="container">IoC容器实例,用于解析依赖。</param>
|
||||
void RegisterBuiltInModules(IIocContainer container);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有已注册的服务模块。
|
||||
/// </summary>
|
||||
/// <returns>只读的服务模块列表。</returns>
|
||||
IReadOnlyList<IServiceModule> GetModules();
|
||||
|
||||
/// <summary>
|
||||
/// 异步初始化所有已注册的服务模块。
|
||||
/// </summary>
|
||||
/// <param name="asyncMode">是否以异步模式初始化模块。</param>
|
||||
/// <returns>表示异步操作的任务。</returns>
|
||||
Task InitializeAllAsync(bool asyncMode);
|
||||
|
||||
/// <summary>
|
||||
/// 异步销毁所有已注册的服务模块。
|
||||
/// </summary>
|
||||
/// <returns>表示异步操作的值任务。</returns>
|
||||
ValueTask DestroyAllAsync();
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
// Copyright (c) 2026 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.Bases;
|
||||
|
||||
/// <summary>
|
||||
/// 定义具有键值访问能力的接口契约
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">键的类型</typeparam>
|
||||
public interface IHasKey<out TKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取对象的键值
|
||||
/// </summary>
|
||||
TKey Key { get; }
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Bases;
|
||||
|
||||
/// <summary>
|
||||
/// 表示键值对的接口,定义了通用的键值对数据结构契约
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">键的类型</typeparam>
|
||||
/// <typeparam name="TValue">值的类型</typeparam>
|
||||
public interface IKeyValue<out TKey, out TValue>
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取键值对中的键
|
||||
/// </summary>
|
||||
TKey Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取键值对中的值
|
||||
/// </summary>
|
||||
TValue Value { get; }
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Bases;
|
||||
|
||||
/// <summary>
|
||||
/// 定义具有优先级的对象接口。
|
||||
/// 数值越小优先级越高,越先执行。
|
||||
/// 用于控制服务、系统等组件的执行顺序。
|
||||
/// </summary>
|
||||
public interface IPrioritized
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取优先级值。
|
||||
/// 数值越小优先级越高。
|
||||
/// 默认优先级为 0。
|
||||
/// 建议范围:-1000 到 1000。
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Bases;
|
||||
|
||||
/// <summary>
|
||||
/// 预定义的优先级分组常量
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 提供标准化的优先级值,用于统一管理系统、服务等组件的执行顺序。
|
||||
/// 优先级值越小,优先级越高(负数表示高优先级)。
|
||||
/// </remarks>
|
||||
public static class PriorityGroup
|
||||
{
|
||||
/// <summary>
|
||||
/// 关键优先级 - 最高优先级,用于核心系统和基础设施
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 适用场景:
|
||||
/// - 日志系统
|
||||
/// - 配置管理
|
||||
/// - IoC 容器初始化
|
||||
/// - 架构核心组件
|
||||
/// </remarks>
|
||||
public const int Critical = -100;
|
||||
|
||||
/// <summary>
|
||||
/// 高优先级 - 用于重要但非核心的系统
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 适用场景:
|
||||
/// - 事件总线
|
||||
/// - 资源管理器
|
||||
/// - 输入系统
|
||||
/// - 网络管理器
|
||||
/// </remarks>
|
||||
public const int High = -50;
|
||||
|
||||
/// <summary>
|
||||
/// 普通优先级 - 默认优先级
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 适用场景:
|
||||
/// - 游戏逻辑系统
|
||||
/// - UI 系统
|
||||
/// - 音频系统
|
||||
/// - 大部分业务逻辑
|
||||
/// </remarks>
|
||||
public const int Normal = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 低优先级 - 用于非关键系统
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 适用场景:
|
||||
/// - 统计系统
|
||||
/// - 调试工具
|
||||
/// - 性能监控
|
||||
/// - 辅助功能
|
||||
/// </remarks>
|
||||
public const int Low = 50;
|
||||
|
||||
/// <summary>
|
||||
/// 延迟优先级 - 最低优先级,用于可延迟执行的系统
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 适用场景:
|
||||
/// - 分析和遥测
|
||||
/// - 后台数据同步
|
||||
/// - 缓存清理
|
||||
/// - 非紧急任务
|
||||
/// </remarks>
|
||||
public const int Deferred = 100;
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
using GFramework.Core.Abstractions.Rule;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Command;
|
||||
|
||||
/// <summary>
|
||||
/// 表示一个异步命令接口,该命令不返回结果
|
||||
/// </summary>
|
||||
public interface IAsyncCommand : IContextAware
|
||||
{
|
||||
/// <summary>
|
||||
/// 异步执行命令
|
||||
/// </summary>
|
||||
/// <returns>表示异步操作的任务</returns>
|
||||
Task ExecuteAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表示一个异步命令接口,该命令返回指定类型的结果
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">命令执行结果的类型</typeparam>
|
||||
public interface IAsyncCommand<TResult> : IContextAware
|
||||
{
|
||||
/// <summary>
|
||||
/// 异步执行命令并返回结果
|
||||
/// </summary>
|
||||
/// <returns>表示异步操作的任务,任务结果为命令执行的返回值</returns>
|
||||
Task<TResult> ExecuteAsync();
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Command;
|
||||
|
||||
/// <summary>
|
||||
/// 定义命令执行器接口,提供同步和异步方式发送并执行命令的方法。
|
||||
/// </summary>
|
||||
public interface ICommandExecutor
|
||||
{
|
||||
/// <summary>
|
||||
/// 发送并执行一个命令。
|
||||
/// </summary>
|
||||
/// <param name="command">要执行的命令对象,实现 ICommand 接口。</param>
|
||||
public void Send(ICommand command);
|
||||
|
||||
/// <summary>
|
||||
/// 发送并执行一个带返回值的命令。
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">命令执行结果的类型。</typeparam>
|
||||
/// <param name="command">要执行的带返回值的命令对象,实现 ICommand<TResult> 接口。</param>
|
||||
/// <returns>命令执行的结果,类型为 TResult。</returns>
|
||||
public TResult Send<TResult>(ICommand<TResult> command);
|
||||
|
||||
/// <summary>
|
||||
/// 发送并异步执行一个命令。
|
||||
/// </summary>
|
||||
/// <param name="command">要执行的命令对象,实现 IAsyncCommand 接口。</param>
|
||||
/// <returns>表示异步操作的任务。</returns>
|
||||
Task SendAsync(IAsyncCommand command);
|
||||
|
||||
/// <summary>
|
||||
/// 发送并异步执行一个带返回值的命令。
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">命令执行结果的类型。</typeparam>
|
||||
/// <param name="command">要执行的带返回值的命令对象,实现 IAsyncCommand<TResult> 接口。</param>
|
||||
/// <returns>表示异步操作的任务,其结果为命令执行的结果,类型为 TResult。</returns>
|
||||
Task<TResult> SendAsync<TResult>(IAsyncCommand<TResult> command);
|
||||
}
|
||||
@ -1,49 +0,0 @@
|
||||
// Copyright (c) 2025 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using GFramework.Core.Abstractions.Utility;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Concurrency;
|
||||
|
||||
/// <summary>
|
||||
/// 异步键锁管理器接口,提供基于键的细粒度锁机制
|
||||
/// </summary>
|
||||
public interface IAsyncKeyLockManager : IUtility, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 异步获取指定键的锁(推荐使用)
|
||||
/// </summary>
|
||||
/// <param name="key">锁键</param>
|
||||
/// <param name="cancellationToken">取消令牌</param>
|
||||
/// <returns>锁句柄,使用 await using 自动释放</returns>
|
||||
ValueTask<IAsyncLockHandle> AcquireLockAsync(string key, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 同步获取指定键的锁(兼容性方法)
|
||||
/// </summary>
|
||||
/// <param name="key">锁键</param>
|
||||
/// <returns>锁句柄,使用 using 自动释放</returns>
|
||||
IAsyncLockHandle AcquireLock(string key);
|
||||
|
||||
/// <summary>
|
||||
/// 获取锁管理器的统计信息
|
||||
/// </summary>
|
||||
/// <returns>统计信息快照</returns>
|
||||
LockStatistics GetStatistics();
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前活跃的锁信息(用于调试)
|
||||
/// </summary>
|
||||
/// <returns>键到锁信息的只读字典</returns>
|
||||
IReadOnlyDictionary<string, LockInfo> GetActiveLocks();
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
// Copyright (c) 2025 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.Concurrency;
|
||||
|
||||
/// <summary>
|
||||
/// 异步锁句柄接口,支持 await using 语法
|
||||
/// </summary>
|
||||
public interface IAsyncLockHandle : IAsyncDisposable, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 锁的键
|
||||
/// </summary>
|
||||
string Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 锁获取时的时间戳(Environment.TickCount64)
|
||||
/// </summary>
|
||||
long AcquiredTicks { get; }
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
// Copyright (c) 2025 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.Concurrency;
|
||||
|
||||
/// <summary>
|
||||
/// 锁信息(用于调试)
|
||||
/// </summary>
|
||||
public readonly struct LockInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 锁的键。
|
||||
/// </summary>
|
||||
public string Key { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前引用计数。
|
||||
/// </summary>
|
||||
public int ReferenceCount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 最后访问时间戳(Environment.TickCount64)。
|
||||
/// </summary>
|
||||
public long LastAccessTicks { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 等待队列长度(近似值)。
|
||||
/// 注意:这是一个基于 SemaphoreSlim.CurrentCount 的近似指示器,
|
||||
/// 当 CurrentCount == 0 时表示锁被持有且可能有等待者,返回 1;
|
||||
/// 否则返回 0。这不是精确的等待者数量,仅用于调试参考。
|
||||
/// </summary>
|
||||
public int WaitingCount { get; init; }
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
// Copyright (c) 2025 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Concurrency;
|
||||
|
||||
/// <summary>
|
||||
/// 锁统计信息
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public readonly struct LockStatistics
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前活跃的锁数量
|
||||
/// </summary>
|
||||
public int ActiveLockCount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 累计获取锁的次数
|
||||
/// </summary>
|
||||
public int TotalAcquired { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 累计释放锁的次数
|
||||
/// </summary>
|
||||
public int TotalReleased { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 累计清理的锁数量
|
||||
/// </summary>
|
||||
public int TotalCleaned { get; init; }
|
||||
}
|
||||
@ -1,99 +0,0 @@
|
||||
using GFramework.Core.Abstractions.Events;
|
||||
using GFramework.Core.Abstractions.Utility;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// 配置管理器接口,提供类型安全的配置存储和访问
|
||||
/// 线程安全:所有方法都是线程安全的
|
||||
/// </summary>
|
||||
public interface IConfigurationManager : IUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取配置数量
|
||||
/// </summary>
|
||||
int Count { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定键的配置值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">配置值类型</typeparam>
|
||||
/// <param name="key">配置键</param>
|
||||
/// <returns>配置值,如果不存在则返回类型默认值</returns>
|
||||
T? GetConfig<T>(string key);
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定键的配置值,如果不存在则返回默认值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">配置值类型</typeparam>
|
||||
/// <param name="key">配置键</param>
|
||||
/// <param name="defaultValue">默认值</param>
|
||||
/// <returns>配置值或默认值</returns>
|
||||
T GetConfig<T>(string key, T defaultValue);
|
||||
|
||||
/// <summary>
|
||||
/// 设置指定键的配置值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">配置值类型</typeparam>
|
||||
/// <param name="key">配置键</param>
|
||||
/// <param name="value">配置值</param>
|
||||
void SetConfig<T>(string key, T value);
|
||||
|
||||
/// <summary>
|
||||
/// 检查指定键的配置是否存在
|
||||
/// </summary>
|
||||
/// <param name="key">配置键</param>
|
||||
/// <returns>如果存在返回 true,否则返回 false</returns>
|
||||
bool HasConfig(string key);
|
||||
|
||||
/// <summary>
|
||||
/// 移除指定键的配置
|
||||
/// </summary>
|
||||
/// <param name="key">配置键</param>
|
||||
/// <returns>如果成功移除返回 true,否则返回 false</returns>
|
||||
bool RemoveConfig(string key);
|
||||
|
||||
/// <summary>
|
||||
/// 清空所有配置
|
||||
/// </summary>
|
||||
void Clear();
|
||||
|
||||
/// <summary>
|
||||
/// 监听指定键的配置变化
|
||||
/// </summary>
|
||||
/// <typeparam name="T">配置值类型</typeparam>
|
||||
/// <param name="key">配置键</param>
|
||||
/// <param name="onChange">配置变化时的回调,参数为新值</param>
|
||||
/// <returns>取消注册接口</returns>
|
||||
IUnRegister WatchConfig<T>(string key, Action<T> onChange);
|
||||
|
||||
/// <summary>
|
||||
/// 从 JSON 字符串加载配置
|
||||
/// </summary>
|
||||
/// <param name="json">JSON 字符串</param>
|
||||
void LoadFromJson(string json);
|
||||
|
||||
/// <summary>
|
||||
/// 将配置保存为 JSON 字符串
|
||||
/// </summary>
|
||||
/// <returns>JSON 字符串</returns>
|
||||
string SaveToJson();
|
||||
|
||||
/// <summary>
|
||||
/// 从文件加载配置
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
void LoadFromFile(string path);
|
||||
|
||||
/// <summary>
|
||||
/// 将配置保存到文件
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
void SaveToFile(string path);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有配置键
|
||||
/// </summary>
|
||||
/// <returns>配置键集合</returns>
|
||||
IEnumerable<string> GetAllKeys();
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Controller;
|
||||
|
||||
/// <summary>
|
||||
/// 控制器标记接口,用于标识控制器组件
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// IController 是一个标记接口(Marker Interface),不包含任何方法或属性。
|
||||
/// 它的作用是标识一个类是控制器,用于协调 Model、System 和 UI 之间的交互。
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// 架构访问 :控制器通常需要访问架构上下文。使用 [ContextAware] 特性
|
||||
/// 自动生成上下文访问能力:
|
||||
/// </para>
|
||||
/// <code>
|
||||
/// using GFramework.SourceGenerators.Abstractions.Rule;
|
||||
///
|
||||
/// [ContextAware]
|
||||
/// public partial class PlayerController : IController
|
||||
/// {
|
||||
/// public void Initialize()
|
||||
/// {
|
||||
/// // [ContextAware] 实现 IContextAware 接口,可使用扩展方法
|
||||
/// var playerModel = this.GetModel<PlayerModel>();
|
||||
/// var gameSystem = this.GetSystem<GameSystem>();
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// <para>
|
||||
/// 注意:
|
||||
/// </para>
|
||||
/// <list type="bullet">
|
||||
/// <item>必须添加 partial 关键字</item>
|
||||
/// <item>[ContextAware] 特性会自动实现 IContextAware 接口</item>
|
||||
/// <item>可使用 this.GetModel()、this.GetSystem() 等扩展方法访问架构</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
public interface IController;
|
||||
@ -1,33 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 协程优先级枚举
|
||||
/// 定义协程的执行优先级,高优先级的协程会优先执行
|
||||
/// </summary>
|
||||
public enum CoroutinePriority
|
||||
{
|
||||
/// <summary>
|
||||
/// 最低优先级
|
||||
/// </summary>
|
||||
Lowest = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 低优先级
|
||||
/// </summary>
|
||||
Low = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 普通优先级(默认)
|
||||
/// </summary>
|
||||
Normal = 2,
|
||||
|
||||
/// <summary>
|
||||
/// 高优先级
|
||||
/// </summary>
|
||||
High = 3,
|
||||
|
||||
/// <summary>
|
||||
/// 最高优先级
|
||||
/// </summary>
|
||||
Highest = 4
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 表示协程的执行状态枚举
|
||||
/// </summary>
|
||||
public enum CoroutineState
|
||||
{
|
||||
/// <summary>
|
||||
/// 协程正在运行中
|
||||
/// </summary>
|
||||
Running,
|
||||
|
||||
/// <summary>
|
||||
/// 协程已暂停
|
||||
/// </summary>
|
||||
Paused,
|
||||
|
||||
/// <summary>
|
||||
/// 协程已完成执行
|
||||
/// </summary>
|
||||
Completed,
|
||||
|
||||
/// <summary>
|
||||
/// 协程已被取消
|
||||
/// </summary>
|
||||
Cancelled
|
||||
}
|
||||
@ -1,68 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 协程统计信息接口
|
||||
/// 提供协程执行的性能统计数据
|
||||
/// </summary>
|
||||
public interface ICoroutineStatistics
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取总协程启动数量
|
||||
/// </summary>
|
||||
long TotalStarted { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取总协程完成数量
|
||||
/// </summary>
|
||||
long TotalCompleted { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取总协程失败数量
|
||||
/// </summary>
|
||||
long TotalFailed { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前活跃协程数量
|
||||
/// </summary>
|
||||
int ActiveCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前暂停协程数量
|
||||
/// </summary>
|
||||
int PausedCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取协程平均执行时间(毫秒)
|
||||
/// </summary>
|
||||
double AverageExecutionTimeMs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取协程最大执行时间(毫秒)
|
||||
/// </summary>
|
||||
double MaxExecutionTimeMs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取按优先级分组的协程数量
|
||||
/// </summary>
|
||||
/// <param name="priority">协程优先级</param>
|
||||
/// <returns>指定优先级的协程数量</returns>
|
||||
int GetCountByPriority(CoroutinePriority priority);
|
||||
|
||||
/// <summary>
|
||||
/// 获取按标签分组的协程数量
|
||||
/// </summary>
|
||||
/// <param name="tag">协程标签</param>
|
||||
/// <returns>指定标签的协程数量</returns>
|
||||
int GetCountByTag(string tag);
|
||||
|
||||
/// <summary>
|
||||
/// 重置统计数据
|
||||
/// </summary>
|
||||
void Reset();
|
||||
|
||||
/// <summary>
|
||||
/// 生成统计报告
|
||||
/// </summary>
|
||||
/// <returns>格式化的统计报告字符串</returns>
|
||||
string GenerateReport();
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 时间源接口,提供当前时间、时间增量以及更新功能
|
||||
/// </summary>
|
||||
public interface ITimeSource
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前时间
|
||||
/// </summary>
|
||||
double CurrentTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取时间增量(上一帧到当前帧的时间差)
|
||||
/// </summary>
|
||||
double DeltaTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间源的状态
|
||||
/// </summary>
|
||||
void Update();
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 定义一个可等待指令的接口,用于协程系统中的异步操作控制
|
||||
/// </summary>
|
||||
public interface IYieldInstruction
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前等待指令是否已完成执行
|
||||
/// </summary>
|
||||
bool IsDone { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 每帧由调度器调用,用于更新当前等待指令的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上一帧以来的时间间隔(以秒为单位)</param>
|
||||
void Update(double deltaTime);
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Cqrs.Command;
|
||||
|
||||
/// <summary>
|
||||
/// 命令输入接口,定义命令模式中输入数据的契约
|
||||
/// 该接口作为标记接口使用,不包含任何成员定义
|
||||
/// </summary>
|
||||
public interface ICommandInput : IInput;
|
||||
@ -1,20 +0,0 @@
|
||||
// Copyright (c) 2026 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.Cqrs;
|
||||
|
||||
/// <summary>
|
||||
/// 表示输入数据的标记接口。
|
||||
/// 该接口用于标识各类CQRS模式中的输入参数类型。
|
||||
/// </summary>
|
||||
public interface IInput;
|
||||
@ -1,20 +0,0 @@
|
||||
// Copyright (c) 2026 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.Cqrs.Notification;
|
||||
|
||||
/// <summary>
|
||||
/// 表示通知输入数据的标记接口。
|
||||
/// 该接口继承自 IInput,用于标识CQRS模式中通知类型的输入参数。
|
||||
/// </summary>
|
||||
public interface INotificationInput : IInput;
|
||||
@ -1,6 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Cqrs.Query;
|
||||
|
||||
/// <summary>
|
||||
/// 查询输入接口,定义了查询操作的输入规范
|
||||
/// </summary>
|
||||
public interface IQueryInput : IInput;
|
||||
@ -1,20 +0,0 @@
|
||||
// Copyright (c) 2026 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.Cqrs.Request;
|
||||
|
||||
/// <summary>
|
||||
/// 表示请求输入数据的标记接口。
|
||||
/// 该接口继承自 IInput,用于标识CQRS模式中请求类型的输入参数。
|
||||
/// </summary>
|
||||
public interface IRequestInput : IInput;
|
||||
@ -1,27 +0,0 @@
|
||||
// Copyright (c) 2025 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.Data;
|
||||
|
||||
/// <summary>
|
||||
/// 定义从指定类型数据源加载数据的接口
|
||||
/// </summary>
|
||||
/// <typeparam name="T">数据源的类型</typeparam>
|
||||
public interface ILoadableFrom<in T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 从指定的数据源加载数据到当前对象
|
||||
/// </summary>
|
||||
/// <param name="source">用作数据源的对象,类型为T</param>
|
||||
void LoadFrom(T source);
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
<Project>
|
||||
<!-- import parent: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build -->
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<!--
|
||||
we use a higher version than supported by the target framework to have nullable types and other nice features
|
||||
(a lot of features get polyfilled by Meziantou.Polyfill)
|
||||
however we need to be careful with the available features!
|
||||
-->
|
||||
<LangVersion>preview</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.264">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Meziantou.Polyfill" Version="1.0.71">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -1,66 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// 架构阶段枚举,定义了系统架构初始化和运行过程中的各个关键阶段
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 该枚举用于标记和控制系统架构组件的生命周期,确保在正确的时机执行相应的初始化和处理逻辑。
|
||||
/// 各个阶段按照时间顺序排列,从创建到准备就绪的完整流程。
|
||||
/// </remarks>
|
||||
public enum ArchitecturePhase
|
||||
{
|
||||
/// <summary>
|
||||
/// 无效阶段,表示未定义的阶段
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 工具类初始化之前阶段
|
||||
/// </summary>
|
||||
BeforeUtilityInit,
|
||||
|
||||
/// <summary>
|
||||
/// 工具类初始化之后阶段
|
||||
/// </summary>
|
||||
AfterUtilityInit,
|
||||
|
||||
/// <summary>
|
||||
/// 模型初始化之前阶段
|
||||
/// </summary>
|
||||
BeforeModelInit,
|
||||
|
||||
/// <summary>
|
||||
/// 模型初始化之后阶段
|
||||
/// </summary>
|
||||
AfterModelInit,
|
||||
|
||||
/// <summary>
|
||||
/// 系统初始化之前阶段
|
||||
/// </summary>
|
||||
BeforeSystemInit,
|
||||
|
||||
/// <summary>
|
||||
/// 系统初始化之后阶段
|
||||
/// </summary>
|
||||
AfterSystemInit,
|
||||
|
||||
/// <summary>
|
||||
/// 就绪阶段,完成冻结和事件处理后的最终状态
|
||||
/// </summary>
|
||||
Ready,
|
||||
|
||||
/// <summary>
|
||||
/// 正在销毁中 暂时不使用
|
||||
/// </summary>
|
||||
Destroying,
|
||||
|
||||
/// <summary>
|
||||
/// 已销毁 暂时不使用
|
||||
/// </summary>
|
||||
Destroyed,
|
||||
|
||||
/// <summary>
|
||||
/// 初始化失败 暂时不使用
|
||||
/// </summary>
|
||||
FailedInitialization
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Environment;
|
||||
|
||||
/// <summary>
|
||||
/// 定义环境接口,提供应用程序运行环境的相关信息
|
||||
/// </summary>
|
||||
public interface IEnvironment
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取环境名称
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据键值获取指定类型的环境配置值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要获取的值的类型,必须为引用类型</typeparam>
|
||||
/// <param name="key">用于查找配置值的键</param>
|
||||
/// <returns>与指定键关联的配置值,如果未找到则返回null</returns>
|
||||
T? Get<T>(string key) where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取环境值(显式判断)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要获取的值的类型,必须为引用类型</typeparam>
|
||||
/// <param name="key">用于查找配置值的键</param>
|
||||
/// <param name="value">输出参数,如果找到配置值则返回该值,否则返回默认值</param>
|
||||
/// <returns>如果找到指定键的配置值则返回true,否则返回false</returns>
|
||||
bool TryGet<T>(string key, out T value) where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 获取必须存在的环境值(强依赖)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要获取的值的类型,必须为引用类型</typeparam>
|
||||
/// <param name="key">用于查找配置值的键</param>
|
||||
/// <returns>与指定键关联的配置值,如果未找到则抛出异常</returns>
|
||||
T GetRequired<T>(string key) where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 注册键值对到环境值字典中
|
||||
/// </summary>
|
||||
/// <param name="key">要注册的键</param>
|
||||
/// <param name="value">要注册的值</param>
|
||||
void Register(string key, object value);
|
||||
|
||||
/// <summary>
|
||||
/// 初始化环境值字典
|
||||
/// </summary>
|
||||
void Initialize();
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// 事件上下文,包装事件数据并提供控制方法
|
||||
/// </summary>
|
||||
/// <typeparam name="T">事件数据类型</typeparam>
|
||||
public class EventContext<T>(T data)
|
||||
{
|
||||
/// <summary>
|
||||
/// 事件数据
|
||||
/// </summary>
|
||||
public T Data { get; } = data;
|
||||
|
||||
/// <summary>
|
||||
/// 事件是否已被处理
|
||||
/// </summary>
|
||||
public bool IsHandled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标记事件为已处理,停止后续传播(仅对 UntilHandled 模式有效)
|
||||
/// </summary>
|
||||
public void MarkAsHandled()
|
||||
{
|
||||
IsHandled = true;
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// 事件传播模式
|
||||
/// </summary>
|
||||
public enum EventPropagation
|
||||
{
|
||||
/// <summary>
|
||||
/// 传播到所有处理器
|
||||
/// </summary>
|
||||
All,
|
||||
|
||||
/// <summary>
|
||||
/// 传播直到某个处理器标记为已处理
|
||||
/// </summary>
|
||||
UntilHandled,
|
||||
|
||||
/// <summary>
|
||||
/// 仅传播到最高优先级的处理器
|
||||
/// </summary>
|
||||
Highest
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// 事件总线接口,提供事件的发送、注册和注销功能
|
||||
/// </summary>
|
||||
public interface IEventBus
|
||||
{
|
||||
/// <summary>
|
||||
/// 发送事件,自动创建事件实例
|
||||
/// </summary>
|
||||
/// <typeparam name="T">事件类型,必须具有无参构造函数</typeparam>
|
||||
void Send<T>() where T : new();
|
||||
|
||||
/// <summary>
|
||||
/// 发送指定的事件实例
|
||||
/// </summary>
|
||||
/// <typeparam name="T">事件类型</typeparam>
|
||||
/// <param name="e">事件实例</param>
|
||||
void Send<T>(T e);
|
||||
|
||||
/// <summary>
|
||||
/// 发送指定的事件实例,并指定传播模式
|
||||
/// </summary>
|
||||
/// <typeparam name="T">事件类型</typeparam>
|
||||
/// <param name="e">事件实例</param>
|
||||
/// <param name="propagation">事件传播模式</param>
|
||||
void Send<T>(T e, EventPropagation propagation);
|
||||
|
||||
/// <summary>
|
||||
/// 注册事件监听器
|
||||
/// </summary>
|
||||
/// <typeparam name="T">事件类型</typeparam>
|
||||
/// <param name="onEvent">事件处理回调函数</param>
|
||||
/// <returns>反注册接口,用于注销事件监听</returns>
|
||||
IUnRegister Register<T>(Action<T> onEvent);
|
||||
|
||||
/// <summary>
|
||||
/// 注册事件监听器,并指定优先级
|
||||
/// </summary>
|
||||
/// <typeparam name="T">事件类型</typeparam>
|
||||
/// <param name="onEvent">事件处理回调函数</param>
|
||||
/// <param name="priority">优先级,数值越大优先级越高</param>
|
||||
/// <returns>反注册接口,用于注销事件监听</returns>
|
||||
IUnRegister Register<T>(Action<T> onEvent, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 注销事件监听器
|
||||
/// </summary>
|
||||
/// <typeparam name="T">事件类型</typeparam>
|
||||
/// <param name="onEvent">要注销的事件处理回调函数</param>
|
||||
void UnRegister<T>(Action<T> onEvent);
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// 事件过滤器接口
|
||||
/// 用于在事件触发前进行条件判断,决定是否允许事件传递给监听器
|
||||
/// </summary>
|
||||
/// <typeparam name="T">事件类型</typeparam>
|
||||
public interface IEventFilter<in T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 判断事件是否应该被过滤(阻止传递)
|
||||
/// </summary>
|
||||
/// <param name="eventData">事件数据</param>
|
||||
/// <returns>如果返回 true,则事件被过滤(不传递给监听器);如果返回 false,则允许传递</returns>
|
||||
bool ShouldFilter(T eventData);
|
||||
}
|
||||
@ -1,58 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// 事件统计信息接口
|
||||
/// 提供事件系统的性能统计数据
|
||||
/// </summary>
|
||||
public interface IEventStatistics
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取总事件发布数量
|
||||
/// </summary>
|
||||
long TotalPublished { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取总事件处理数量(监听器调用次数)
|
||||
/// </summary>
|
||||
long TotalHandled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取总事件处理失败数量
|
||||
/// </summary>
|
||||
long TotalFailed { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前活跃的事件类型数量
|
||||
/// </summary>
|
||||
int ActiveEventTypes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前活跃的监听器总数
|
||||
/// </summary>
|
||||
int ActiveListeners { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定事件类型的发布次数
|
||||
/// </summary>
|
||||
/// <param name="eventType">事件类型名称</param>
|
||||
/// <returns>发布次数</returns>
|
||||
long GetPublishCount(string eventType);
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定事件类型的监听器数量
|
||||
/// </summary>
|
||||
/// <param name="eventType">事件类型名称</param>
|
||||
/// <returns>监听器数量</returns>
|
||||
int GetListenerCount(string eventType);
|
||||
|
||||
/// <summary>
|
||||
/// 重置统计数据
|
||||
/// </summary>
|
||||
void Reset();
|
||||
|
||||
/// <summary>
|
||||
/// 生成统计报告
|
||||
/// </summary>
|
||||
/// <returns>格式化的统计报告字符串</returns>
|
||||
string GenerateReport();
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<!--
|
||||
配置项目构建属性
|
||||
设置项目生成文档文件,并包含特定的Polyfill
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<PackageId>GeWuYou.$(AssemblyName)</PackageId>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<MeziantouPolyfill_IncludedPolyfills>T:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute</MeziantouPolyfill_IncludedPolyfills>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- 引入必要的命名空间 -->
|
||||
<ItemGroup>
|
||||
<Using Include="GFramework.Core.Abstractions"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="3.0.25">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Update="Meziantou.Polyfill" Version="1.0.104">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Mediator.Abstractions" Version="3.0.1"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2025 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Runtime;
|
||||
global using System.Linq;
|
||||
global using System.Threading;
|
||||
global using System.Threading.Tasks;
|
||||
@ -1,20 +0,0 @@
|
||||
// IsExternalInit.cs
|
||||
// This type is required to support init-only setters and record types
|
||||
// when targeting netstandard2.0 or older frameworks.
|
||||
|
||||
#if !NET5_0_OR_GREATER
|
||||
using System.ComponentModel;
|
||||
|
||||
// ReSharper disable CheckNamespace
|
||||
|
||||
namespace System.Runtime.CompilerServices;
|
||||
|
||||
/// <summary>
|
||||
/// 提供一个占位符类型,用于支持 C# 9.0 的 init 访问器功能。
|
||||
/// 该类型在 .NET 5.0 及更高版本中已内置,因此仅在较低版本的 .NET 中定义。
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
internal static class IsExternalInit
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@ -1,230 +0,0 @@
|
||||
using GFramework.Core.Abstractions.Rule;
|
||||
using GFramework.Core.Abstractions.Systems;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Ioc;
|
||||
|
||||
/// <summary>
|
||||
/// 依赖注入容器接口,定义了服务注册、解析和管理的基本操作
|
||||
/// </summary>
|
||||
public interface IIocContainer : IContextAware
|
||||
{
|
||||
#region Register Methods
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// 一个类型只允许一个实例
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要注册为单例的类型</typeparam>
|
||||
/// <param name="instance">要注册的单例实例</param>
|
||||
/// <exception cref="InvalidOperationException">当该类型已经注册过单例时抛出异常</exception>
|
||||
void RegisterSingleton<T>(T instance);
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例服务,指定服务类型和实现类型
|
||||
/// 创建单例实例并在容器中注册
|
||||
/// </summary>
|
||||
/// <typeparam name="TService">服务接口或基类类型</typeparam>
|
||||
/// <typeparam name="TImpl">具体的实现类型</typeparam>
|
||||
void RegisterSingleton<TService, TImpl>()
|
||||
where TImpl : class, TService where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// 注册瞬态服务,指定服务类型和实现类型
|
||||
/// 每次解析时都会创建新的实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TService">服务接口或基类类型</typeparam>
|
||||
/// <typeparam name="TImpl">具体的实现类型</typeparam>
|
||||
void RegisterTransient<TService, TImpl>()
|
||||
where TImpl : class, TService where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// 注册作用域服务,指定服务类型和实现类型
|
||||
/// 在同一作用域内共享实例,不同作用域使用不同实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TService">服务接口或基类类型</typeparam>
|
||||
/// <typeparam name="TImpl">具体的实现类型</typeparam>
|
||||
void RegisterScoped<TService, TImpl>()
|
||||
where TImpl : class, TService where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// 注册多个实例
|
||||
/// 将实例注册到其实现的所有接口和具体类型上
|
||||
/// </summary>
|
||||
/// <param name="instance">要注册的实例</param>
|
||||
public void RegisterPlurality(object instance);
|
||||
|
||||
/// <summary>
|
||||
/// 注册多个实例
|
||||
/// 将实例注册到其实现所有接口
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要注册的实例类型</typeparam>
|
||||
public void RegisterPlurality<T>() where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 注册系统实例,将其绑定到其所有实现的接口上
|
||||
/// </summary>
|
||||
/// <param name="system">系统实例对象</param>
|
||||
void RegisterSystem(ISystem system);
|
||||
|
||||
/// <summary>
|
||||
/// 注册指定类型的实例到容器中
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要注册的实例类型</typeparam>
|
||||
/// <param name="instance">要注册的实例对象,不能为null</param>
|
||||
void Register<T>(T instance);
|
||||
|
||||
/// <summary>
|
||||
/// 注册指定类型的实例到容器中
|
||||
/// </summary>
|
||||
/// <param name="type">要注册的实例类型</param>
|
||||
/// <param name="instance">要注册的实例对象</param>
|
||||
void Register(Type type, object instance);
|
||||
|
||||
/// <summary>
|
||||
/// 注册工厂方法来创建服务实例
|
||||
/// 通过委托函数动态创建服务实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TService">服务类型</typeparam>
|
||||
/// <param name="factory">创建服务实例的工厂委托函数</param>
|
||||
void RegisterFactory<TService>(Func<IServiceProvider, TService> factory) where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// 注册中介行为管道
|
||||
/// 用于配置Mediator框架的行为拦截和处理逻辑
|
||||
/// </summary>
|
||||
/// <typeparam name="TBehavior">行为类型,必须是引用类型</typeparam>
|
||||
void RegisterMediatorBehavior<TBehavior>()
|
||||
where TBehavior : class;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 配置服务
|
||||
/// </summary>
|
||||
/// <param name="configurator">服务配置委托</param>
|
||||
void ExecuteServicesHook(Action<IServiceCollection>? configurator = null);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get Methods
|
||||
|
||||
/// <summary>
|
||||
/// 获取单个实例(通常用于具体类型)
|
||||
/// 如果存在多个,只返回第一个
|
||||
/// </summary>
|
||||
/// <typeparam name="T">期望获取的实例类型</typeparam>
|
||||
/// <returns>找到的第一个实例;如果未找到则返回 null</returns>
|
||||
T? Get<T>() where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 根据指定类型获取单个实例
|
||||
/// 如果存在多个,只返回第一个
|
||||
/// </summary>
|
||||
/// <param name="type">期望获取的实例类型</param>
|
||||
/// <returns>找到的第一个实例;如果未找到则返回 null</returns>
|
||||
object? Get(Type type);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的必需实例
|
||||
/// </summary>
|
||||
/// <typeparam name="T">期望获取的实例类型</typeparam>
|
||||
/// <returns>找到的唯一实例</returns>
|
||||
/// <exception cref="InvalidOperationException">当没有注册实例或注册了多个实例时抛出</exception>
|
||||
T GetRequired<T>() where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的必需实例
|
||||
/// </summary>
|
||||
/// <param name="type">期望获取的实例类型</param>
|
||||
/// <returns>找到的唯一实例</returns>
|
||||
/// <exception cref="InvalidOperationException">当没有注册实例或注册了多个实例时抛出</exception>
|
||||
object GetRequired(Type type);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有实例(接口 / 抽象类推荐使用)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">期望获取的实例类型</typeparam>
|
||||
/// <returns>所有符合条件的实例列表;如果没有则返回空数组</returns>
|
||||
IReadOnlyList<T> GetAll<T>() where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有实例
|
||||
/// </summary>
|
||||
/// <param name="type">期望获取的实例类型</param>
|
||||
/// <returns>所有符合条件的实例列表;如果没有则返回空数组</returns>
|
||||
IReadOnlyList<object> GetAll(Type type);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取并排序(系统调度专用)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">期望获取的实例类型</typeparam>
|
||||
/// <param name="comparison">比较器委托,定义排序规则</param>
|
||||
/// <returns>按指定方式排序后的实例列表</returns>
|
||||
IReadOnlyList<T> GetAllSorted<T>(Comparison<T> comparison) where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有实例,并按优先级排序
|
||||
/// 实现 IPrioritized 接口的服务将按优先级排序(数值越小优先级越高)
|
||||
/// 未实现 IPrioritized 的服务将使用默认优先级 0
|
||||
/// </summary>
|
||||
/// <typeparam name="T">期望获取的实例类型</typeparam>
|
||||
/// <returns>按优先级排序后的实例列表</returns>
|
||||
IReadOnlyList<T> GetAllByPriority<T>() where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有实例,并按优先级排序
|
||||
/// 实现 IPrioritized 接口的服务将按优先级排序(数值越小优先级越高)
|
||||
/// 未实现 IPrioritized 的服务将使用默认优先级 0
|
||||
/// </summary>
|
||||
/// <param name="type">期望获取的实例类型</param>
|
||||
/// <returns>按优先级排序后的实例列表</returns>
|
||||
IReadOnlyList<object> GetAllByPriority(Type type);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Utility Methods
|
||||
|
||||
/// <summary>
|
||||
/// 检查容器中是否包含指定类型的实例
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要检查的类型</typeparam>
|
||||
/// <returns>如果容器中包含指定类型的实例则返回true,否则返回false</returns>
|
||||
bool Contains<T>() where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 判断容器中是否包含某个具体的实例对象
|
||||
/// </summary>
|
||||
/// <param name="instance">待查询的实例对象</param>
|
||||
/// <returns>若容器中包含该实例则返回true,否则返回false</returns>
|
||||
bool ContainsInstance(object instance);
|
||||
|
||||
/// <summary>
|
||||
/// 清空容器中的所有实例
|
||||
/// </summary>
|
||||
void Clear();
|
||||
|
||||
/// <summary>
|
||||
/// 冻结容器,防止后续修改
|
||||
/// 调用此方法后,容器将变为只读状态,不能再注册新的服务实例
|
||||
/// </summary>
|
||||
void Freeze();
|
||||
|
||||
/// <summary>
|
||||
/// 获取底层的服务集合
|
||||
/// 提供对内部IServiceCollection的访问权限,用于高级配置和自定义操作
|
||||
/// </summary>
|
||||
/// <returns>底层的IServiceCollection实例</returns>
|
||||
IServiceCollection GetServicesUnsafe { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个新的服务作用域
|
||||
/// 作用域内的 Scoped 服务将共享同一实例
|
||||
/// </summary>
|
||||
/// <returns>服务作用域实例</returns>
|
||||
IServiceScope CreateScope();
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
/// <summary>
|
||||
/// 定义异步销毁接口,用于需要异步清理资源的组件
|
||||
/// </summary>
|
||||
public interface IAsyncDestroyable
|
||||
{
|
||||
/// <summary>
|
||||
/// 异步销毁方法,在组件关闭时调用
|
||||
/// </summary>
|
||||
/// <returns>表示异步销毁操作的任务</returns>
|
||||
ValueTask DestroyAsync();
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
/// <summary>
|
||||
/// 定义异步初始化接口,用于需要异步初始化的组件或服务
|
||||
/// </summary>
|
||||
public interface IAsyncInitializable
|
||||
{
|
||||
/// <summary>
|
||||
/// 异步初始化方法,用于执行组件或服务的异步初始化逻辑
|
||||
/// </summary>
|
||||
/// <returns>表示异步初始化操作的Task</returns>
|
||||
Task InitializeAsync();
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
/// <summary>
|
||||
/// 定义异步生命周期接口,组合了异步初始化和异步销毁
|
||||
/// </summary>
|
||||
public interface IAsyncLifecycle : IAsyncInitializable, IAsyncDestroyable
|
||||
{
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
/// <summary>
|
||||
/// 可销毁接口,为需要资源清理的组件提供标准销毁能力
|
||||
/// </summary>
|
||||
public interface IDestroyable
|
||||
{
|
||||
/// <summary>
|
||||
/// 销毁组件并释放资源
|
||||
/// </summary>
|
||||
void Destroy();
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
/// <summary>
|
||||
/// 可初始化接口,为需要初始化的组件提供标准初始化能力
|
||||
/// </summary>
|
||||
public interface IInitializable
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化组件
|
||||
/// </summary>
|
||||
void Initialize();
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
/// <summary>
|
||||
/// 完整生命周期接口,组合了初始化和销毁能力
|
||||
/// </summary>
|
||||
public interface ILifecycle : IInitializable, IDestroyable;
|
||||
@ -1,22 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Localization;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化格式化器接口
|
||||
/// </summary>
|
||||
public interface ILocalizationFormatter
|
||||
{
|
||||
/// <summary>
|
||||
/// 格式化器名称
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 尝试格式化值
|
||||
/// </summary>
|
||||
/// <param name="format">格式字符串</param>
|
||||
/// <param name="value">要格式化的值</param>
|
||||
/// <param name="provider">格式提供者</param>
|
||||
/// <param name="result">格式化结果</param>
|
||||
/// <returns>是否成功格式化</returns>
|
||||
bool TryFormat(string format, object value, IFormatProvider? provider, out string result);
|
||||
}
|
||||
@ -1,89 +0,0 @@
|
||||
using System.Globalization;
|
||||
using GFramework.Core.Abstractions.Systems;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Localization;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化管理器接口
|
||||
/// </summary>
|
||||
public interface ILocalizationManager : ISystem
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前语言代码
|
||||
/// </summary>
|
||||
string CurrentLanguage { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前文化信息
|
||||
/// </summary>
|
||||
CultureInfo CurrentCulture { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 可用语言列表
|
||||
/// </summary>
|
||||
IReadOnlyList<string> AvailableLanguages { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 设置当前语言
|
||||
/// </summary>
|
||||
/// <param name="languageCode">语言代码</param>
|
||||
void SetLanguage(string languageCode);
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地化表
|
||||
/// </summary>
|
||||
/// <param name="tableName">表名</param>
|
||||
/// <returns>本地化表</returns>
|
||||
ILocalizationTable GetTable(string tableName);
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地化文本
|
||||
/// </summary>
|
||||
/// <param name="table">表名</param>
|
||||
/// <param name="key">键名</param>
|
||||
/// <returns>本地化文本</returns>
|
||||
string GetText(string table, string key);
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地化字符串(支持变量和格式化)
|
||||
/// </summary>
|
||||
/// <param name="table">表名</param>
|
||||
/// <param name="key">键名</param>
|
||||
/// <returns>本地化字符串</returns>
|
||||
ILocalizationString GetString(string table, string key);
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取本地化文本
|
||||
/// </summary>
|
||||
/// <param name="table">表名</param>
|
||||
/// <param name="key">键名</param>
|
||||
/// <param name="text">输出文本</param>
|
||||
/// <returns>是否成功获取</returns>
|
||||
bool TryGetText(string table, string key, out string text);
|
||||
|
||||
/// <summary>
|
||||
/// 注册格式化器
|
||||
/// </summary>
|
||||
/// <param name="name">格式化器名称</param>
|
||||
/// <param name="formatter">格式化器实例</param>
|
||||
void RegisterFormatter(string name, ILocalizationFormatter formatter);
|
||||
|
||||
/// <summary>
|
||||
/// 获取格式化器
|
||||
/// </summary>
|
||||
/// <param name="name">格式化器名称</param>
|
||||
/// <returns>格式化器实例,如果不存在则返回 null</returns>
|
||||
ILocalizationFormatter? GetFormatter(string name);
|
||||
|
||||
/// <summary>
|
||||
/// 订阅语言变化事件
|
||||
/// </summary>
|
||||
/// <param name="callback">回调函数</param>
|
||||
void SubscribeToLanguageChange(Action<string> callback);
|
||||
|
||||
/// <summary>
|
||||
/// 取消订阅语言变化事件
|
||||
/// </summary>
|
||||
/// <param name="callback">回调函数</param>
|
||||
void UnsubscribeFromLanguageChange(Action<string> callback);
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Localization;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化字符串接口(支持变量和格式化)
|
||||
/// </summary>
|
||||
public interface ILocalizationString
|
||||
{
|
||||
/// <summary>
|
||||
/// 表名
|
||||
/// </summary>
|
||||
string Table { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 键名
|
||||
/// </summary>
|
||||
string Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 添加变量
|
||||
/// </summary>
|
||||
/// <param name="name">变量名</param>
|
||||
/// <param name="value">变量值</param>
|
||||
/// <returns>当前实例(支持链式调用)</returns>
|
||||
ILocalizationString WithVariable(string name, object value);
|
||||
|
||||
/// <summary>
|
||||
/// 批量添加变量
|
||||
/// </summary>
|
||||
/// <param name="variables">变量数组</param>
|
||||
/// <returns>当前实例(支持链式调用)</returns>
|
||||
ILocalizationString WithVariables(params (string name, object value)[] variables);
|
||||
|
||||
/// <summary>
|
||||
/// 格式化并返回最终文本
|
||||
/// </summary>
|
||||
/// <returns>格式化后的文本</returns>
|
||||
string Format();
|
||||
|
||||
/// <summary>
|
||||
/// 获取原始文本(不进行格式化)
|
||||
/// </summary>
|
||||
/// <returns>原始文本</returns>
|
||||
string GetRaw();
|
||||
|
||||
/// <summary>
|
||||
/// 检查键是否存在
|
||||
/// </summary>
|
||||
/// <returns>是否存在</returns>
|
||||
bool Exists();
|
||||
}
|
||||
@ -1,48 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Localization;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化表接口
|
||||
/// </summary>
|
||||
public interface ILocalizationTable
|
||||
{
|
||||
/// <summary>
|
||||
/// 表名
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 语言代码
|
||||
/// </summary>
|
||||
string Language { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 回退表(当前表中找不到键时使用)
|
||||
/// </summary>
|
||||
ILocalizationTable? Fallback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取原始文本(不进行格式化)
|
||||
/// </summary>
|
||||
/// <param name="key">键名</param>
|
||||
/// <returns>原始文本</returns>
|
||||
string GetRawText(string key);
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否包含指定键
|
||||
/// </summary>
|
||||
/// <param name="key">键名</param>
|
||||
/// <returns>是否包含</returns>
|
||||
bool ContainsKey(string key);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有键
|
||||
/// </summary>
|
||||
/// <returns>键集合</returns>
|
||||
IEnumerable<string> GetKeys();
|
||||
|
||||
/// <summary>
|
||||
/// 合并覆盖数据
|
||||
/// </summary>
|
||||
/// <param name="overrides">覆盖数据</param>
|
||||
void Merge(IReadOnlyDictionary<string, string> overrides);
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
namespace GFramework.Core.Abstractions.Localization;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化配置
|
||||
/// </summary>
|
||||
public class LocalizationConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认语言代码
|
||||
/// </summary>
|
||||
public string DefaultLanguage { get; set; } = "eng";
|
||||
|
||||
/// <summary>
|
||||
/// 回退语言代码(当目标语言缺少键时使用)
|
||||
/// </summary>
|
||||
public string FallbackLanguage { get; set; } = "eng";
|
||||
|
||||
/// <summary>
|
||||
/// 本地化文件路径(Godot 资源路径)
|
||||
/// </summary>
|
||||
public string LocalizationPath { get; set; } = "res://localization";
|
||||
|
||||
/// <summary>
|
||||
/// 用户覆盖文件路径(用于热更新和自定义翻译)
|
||||
/// </summary>
|
||||
public string OverridePath { get; set; } = "user://localization_override";
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用热重载(监视覆盖文件变化)
|
||||
/// </summary>
|
||||
public bool EnableHotReload { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 是否在加载时验证本地化文件
|
||||
/// </summary>
|
||||
public bool ValidateOnLoad { get; set; } = true;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user