refactor(abstractions): 将抽象接口迁移至独立项目并更新引用

- 将架构相关接口从 GFramework.Core 迁移至 GFramework.Core.Abstractions 项目
- 更新项目引用配置,添加对抽象层项目的项目引用
- 修正命名空间引用,使用新的抽象层命名空间
- 调整类型定义,将 List<T> 替换为更通用的 IList<T> 接口
- 修复控制器接口命名空间错误
- 添加必要的 using 语句以支持新的抽象层引用
This commit is contained in:
GwWuYou 2025-12-28 10:37:18 +08:00
parent f638f50eb4
commit 2dea63e69f
71 changed files with 450 additions and 196 deletions

View File

@ -0,0 +1,24 @@
<Project>
<!-- import parent: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build -->
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
<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>

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<!--
配置项目构建属性
设置项目不可打包、生成文档文件并包含特定的Polyfill
-->
<PropertyGroup>
<IsPackable>false</IsPackable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<MeziantouPolyfill_IncludedPolyfills>T:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute</MeziantouPolyfill_IncludedPolyfills>
<Nullable>enable</Nullable>
<TargetFramework/>
</PropertyGroup>
<!-- 引入必要的命名空间 -->
<ItemGroup>
<Using Include="GFramework.Core.Abstractions"/>
</ItemGroup>
</Project>

View File

@ -1,4 +1,4 @@
namespace GFramework.Core.architecture; namespace GFramework.Core.Abstractions.architecture;
/// <summary> /// <summary>
/// 架构选项配置类,用于定义架构行为的相关配置选项 /// 架构选项配置类,用于定义架构行为的相关配置选项
@ -11,10 +11,10 @@ public sealed class ArchitectureOptions(
/// <summary> /// <summary>
/// 允许延迟注册开关当设置为true时允许在初始化完成后进行组件注册 /// 允许延迟注册开关当设置为true时允许在初始化完成后进行组件注册
/// </summary> /// </summary>
public bool AllowLateRegistration = allowLateRegistration; public bool AllowLateRegistration { get; } = allowLateRegistration;
/// <summary> /// <summary>
/// 严格阶段验证开关当设置为true时启用严格的阶段验证机制 /// 严格阶段验证开关当设置为true时启用严格的阶段验证机制
/// </summary> /// </summary>
public bool StrictPhaseValidation = strictPhaseValidation; public bool StrictPhaseValidation { get; } = strictPhaseValidation;
} }

View File

@ -1,8 +1,8 @@
using GFramework.Core.model; using GFramework.Core.Abstractions.model;
using GFramework.Core.system; using GFramework.Core.Abstractions.system;
using GFramework.Core.utility; using GFramework.Core.Abstractions.utility;
namespace GFramework.Core.architecture; namespace GFramework.Core.Abstractions.architecture;
/// <summary> /// <summary>
/// 架构接口,专注于生命周期管理,包括系统、模型、工具的注册和获取 /// 架构接口,专注于生命周期管理,包括系统、模型、工具的注册和获取

View File

@ -1,6 +1,6 @@
using GFramework.Core.logging; using GFramework.Core.Abstractions.logging;
namespace GFramework.Core.architecture; namespace GFramework.Core.Abstractions.architecture;
/// <summary> /// <summary>
/// 定义架构配置的接口,提供日志工厂、日志级别和架构选项的配置功能 /// 定义架构配置的接口,提供日志工厂、日志级别和架构选项的配置功能

View File

@ -1,12 +1,13 @@
using GFramework.Core.command; using System;
using GFramework.Core.events; using GFramework.Core.Abstractions.command;
using GFramework.Core.logging; using GFramework.Core.Abstractions.events;
using GFramework.Core.model; using GFramework.Core.Abstractions.logging;
using GFramework.Core.query; using GFramework.Core.Abstractions.model;
using GFramework.Core.system; using GFramework.Core.Abstractions.query;
using GFramework.Core.utility; using GFramework.Core.Abstractions.system;
using GFramework.Core.Abstractions.utility;
namespace GFramework.Core.architecture; namespace GFramework.Core.Abstractions.architecture;
/// <summary> /// <summary>
/// 架构上下文接口,提供对系统、模型、工具类的访问以及命令、查询、事件的发送和注册功能 /// 架构上下文接口,提供对系统、模型、工具类的访问以及命令、查询、事件的发送和注册功能

View File

@ -1,4 +1,4 @@
namespace GFramework.Core.architecture; namespace GFramework.Core.Abstractions.architecture;
/// <summary> /// <summary>
/// 架构生命周期接口,定义了架构在不同阶段的回调方法 /// 架构生命周期接口,定义了架构在不同阶段的回调方法

View File

@ -1,4 +1,4 @@
namespace GFramework.Core.architecture; namespace GFramework.Core.Abstractions.architecture;
/// <summary> /// <summary>
/// 架构模块接口,继承自架构生命周期接口。 /// 架构模块接口,继承自架构生命周期接口。

View File

@ -1,4 +1,4 @@
namespace GFramework.Core.architecture; namespace GFramework.Core.Abstractions.architecture;
/// <summary> /// <summary>
/// 定义架构阶段感知接口,用于在架构的不同阶段执行相应的逻辑 /// 定义架构阶段感知接口,用于在架构的不同阶段执行相应的逻辑

View File

@ -1,8 +1,9 @@
using GFramework.Core.command; using System;
using GFramework.Core.events; using GFramework.Core.Abstractions.command;
using GFramework.Core.query; using GFramework.Core.Abstractions.events;
using GFramework.Core.Abstractions.query;
namespace GFramework.Core.architecture; namespace GFramework.Core.Abstractions.architecture;
/// <summary> /// <summary>
/// 架构运行时接口,提供统一的命令、查询、事件操作入口 /// 架构运行时接口,提供统一的命令、查询、事件操作入口

View File

@ -1,7 +1,7 @@
using GFramework.Core.events; using GFramework.Core.Abstractions.events;
using GFramework.Core.ioc; using GFramework.Core.Abstractions.ioc;
namespace GFramework.Core.architecture; namespace GFramework.Core.Abstractions.architecture;
/// <summary> /// <summary>
/// 架构服务接口,定义了框架核心架构所需的服务组件 /// 架构服务接口,定义了框架核心架构所需的服务组件

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.architecture; using System.Threading.Tasks;
namespace GFramework.Core.Abstractions.architecture;
/// <summary> /// <summary>
/// 定义异步初始化接口,用于需要异步初始化的组件或服务 /// 定义异步初始化接口,用于需要异步初始化的组件或服务

View File

@ -1,6 +1,6 @@
using GFramework.Core.rule; using GFramework.Core.Abstractions.rule;
namespace GFramework.Core.command; namespace GFramework.Core.Abstractions.command;
/// <summary> /// <summary>
/// 命令接口,定义了无返回值命令的基本契约 /// 命令接口,定义了无返回值命令的基本契约

View File

@ -1,6 +1,6 @@
using GFramework.Core.rule; using GFramework.Core.Abstractions.rule;
namespace GFramework.Core.controller; namespace GFramework.GFramework.Core.Abstractions.controller;
/// <summary> /// <summary>
/// 控制器接口,定义了控制器需要实现的所有功能契约 /// 控制器接口,定义了控制器需要实现的所有功能契约

View File

@ -1,4 +1,4 @@
namespace GFramework.Core.architecture; namespace GFramework.Core.Abstractions.architecture;
/// <summary> /// <summary>
/// 架构阶段枚举,定义了系统架构初始化和运行过程中的各个关键阶段 /// 架构阶段枚举,定义了系统架构初始化和运行过程中的各个关键阶段

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.events; using System;
namespace GFramework.Core.Abstractions.events;
/// <summary> /// <summary>
/// 事件接口,定义了事件注册的基本功能 /// 事件接口,定义了事件注册的基本功能

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.events; using System;
namespace GFramework.Core.Abstractions.events;
/// <summary> /// <summary>
/// 类型事件系统接口,定义基于类型的事件发送、注册和注销功能 /// 类型事件系统接口,定义基于类型的事件发送、注册和注销功能

View File

@ -1,4 +1,4 @@
namespace GFramework.Core.events; namespace GFramework.Core.Abstractions.events;
/// <summary> /// <summary>
/// 提供注销功能的接口 /// 提供注销功能的接口

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.events; using System.Collections.Generic;
namespace GFramework.Core.Abstractions.events;
/// <summary> /// <summary>
/// 提供统一注销功能的接口,用于管理需要注销的对象列表 /// 提供统一注销功能的接口,用于管理需要注销的对象列表
@ -8,5 +10,5 @@ public interface IUnRegisterList
/// <summary> /// <summary>
/// 获取需要注销的对象列表 /// 获取需要注销的对象列表
/// </summary> /// </summary>
List<IUnRegister> UnregisterList { get; } IList<IUnRegister> UnregisterList { get; }
} }

View File

@ -1,7 +1,9 @@
using GFramework.Core.rule; using System;
using GFramework.Core.system; using System.Collections.Generic;
using GFramework.Core.Abstractions.rule;
using GFramework.Core.Abstractions.system;
namespace GFramework.Core.ioc; namespace GFramework.Core.Abstractions.ioc;
/// <summary> /// <summary>
/// 依赖注入容器接口,定义了服务注册、解析和管理的基本操作 /// 依赖注入容器接口,定义了服务注册、解析和管理的基本操作

View File

@ -1,4 +1,7 @@
namespace GFramework.Core.logging; using System;
using GFramework.Core.logging;
namespace GFramework.Core.Abstractions.logging;
/// <summary> /// <summary>
/// 定义日志记录接口,提供日志记录和级别检查功能 /// 定义日志记录接口,提供日志记录和级别检查功能

View File

@ -1,4 +1,4 @@
namespace GFramework.Core.logging; namespace GFramework.Core.Abstractions.logging;
/// <summary> /// <summary>
/// 定义日志工厂接口,用于创建日志记录器实例 /// 定义日志工厂接口,用于创建日志记录器实例

View File

@ -1,4 +1,4 @@
namespace GFramework.Core.model; namespace GFramework.Core.Abstractions.model;
/// <summary> /// <summary>
/// 模型接口,定义了模型的基本行为和功能 /// 模型接口,定义了模型的基本行为和功能

View File

@ -1,4 +1,4 @@
namespace GFramework.Core.property; namespace GFramework.Core.Abstractions.property;
/// <summary> /// <summary>
/// 可绑定属性接口,继承自只读可绑定属性接口,提供可读写的属性绑定功能 /// 可绑定属性接口,继承自只读可绑定属性接口,提供可读写的属性绑定功能

View File

@ -1,6 +1,6 @@
using GFramework.Core.events; using GFramework.Core.Abstractions.events;
namespace GFramework.Core.property; namespace GFramework.Core.Abstractions.property;
/// <summary> /// <summary>
/// 只读可绑定属性接口,提供属性值的读取和变更监听功能 /// 只读可绑定属性接口,提供属性值的读取和变更监听功能

View File

@ -1,6 +1,6 @@
using GFramework.Core.rule; using GFramework.Core.Abstractions.rule;
namespace GFramework.Core.query; namespace GFramework.Core.Abstractions.query;
/// <summary> /// <summary>
/// 查询接口,定义了执行查询操作的契约 /// 查询接口,定义了执行查询操作的契约

View File

@ -1,6 +1,6 @@
using GFramework.Core.architecture; using GFramework.Core.Abstractions.architecture;
namespace GFramework.Core.rule; namespace GFramework.Core.Abstractions.rule;
/// <summary> /// <summary>
/// 上下文感知接口,用于为实现该接口的类提供设置架构上下文的能力 /// 上下文感知接口,用于为实现该接口的类提供设置架构上下文的能力

View File

@ -1,6 +1,6 @@
using GFramework.Core.logging; using GFramework.Core.Abstractions.logging;
namespace GFramework.Core.rule; namespace GFramework.Core.Abstractions.rule;
/// <summary> /// <summary>
/// 定义一个支持日志记录的接口,允许实现类设置和使用日志记录器 /// 定义一个支持日志记录的接口,允许实现类设置和使用日志记录器

View File

@ -1,6 +1,6 @@
using GFramework.Core.rule; using GFramework.Core.Abstractions.rule;
namespace GFramework.Core.system; namespace GFramework.Core.Abstractions.system;
/// <summary> /// <summary>
/// 系统接口,定义了系统的基本行为和功能 /// 系统接口,定义了系统的基本行为和功能

View File

@ -1,6 +1,6 @@
using GFramework.Core.rule; using GFramework.Core.Abstractions.rule;
namespace GFramework.Core.utility; namespace GFramework.Core.Abstractions.utility;
/// <summary> /// <summary>
/// 上下文工具接口继承自IUtility和IContextAware接口 /// 上下文工具接口继承自IUtility和IContextAware接口

View File

@ -1,4 +1,4 @@
namespace GFramework.Core.utility; namespace GFramework.Core.Abstractions.utility;
/// <summary> /// <summary>
/// IUtility接口定义了通用工具类的基本契约 /// IUtility接口定义了通用工具类的基本契约

View File

@ -6,5 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\GFramework.Core.Abstractions\GFramework.Core.Abstractions.csproj"/>
</ItemGroup>
</Project> </Project>

View File

@ -1,9 +1,11 @@
using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.events;
using GFramework.Core.Abstractions.ioc;
using GFramework.Core.Abstractions.logging;
using GFramework.Core.Abstractions.model;
using GFramework.Core.Abstractions.system;
using GFramework.Core.Abstractions.utility;
using GFramework.Core.events; using GFramework.Core.events;
using GFramework.Core.ioc;
using GFramework.Core.logging;
using GFramework.Core.model;
using GFramework.Core.system;
using GFramework.Core.utility;
namespace GFramework.Core.architecture; namespace GFramework.Core.architecture;

View File

@ -1,4 +1,6 @@
using GFramework.Core.logging; using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.logging;
using GFramework.Core.logging;
namespace GFramework.Core.architecture; namespace GFramework.Core.architecture;

View File

@ -1,4 +1,5 @@
using System.Collections.Immutable; using System.Collections.Immutable;
using GFramework.Core.Abstractions.architecture;
namespace GFramework.Core.architecture; namespace GFramework.Core.architecture;

View File

@ -1,11 +1,13 @@
using GFramework.Core.command; using GFramework.Core.Abstractions.architecture;
using GFramework.Core.events; using GFramework.Core.Abstractions.command;
using GFramework.Core.ioc; using GFramework.Core.Abstractions.events;
using GFramework.Core.Abstractions.ioc;
using GFramework.Core.Abstractions.logging;
using GFramework.Core.Abstractions.model;
using GFramework.Core.Abstractions.query;
using GFramework.Core.Abstractions.system;
using GFramework.Core.Abstractions.utility;
using GFramework.Core.logging; using GFramework.Core.logging;
using GFramework.Core.model;
using GFramework.Core.query;
using GFramework.Core.system;
using GFramework.Core.utility;
namespace GFramework.Core.architecture; namespace GFramework.Core.architecture;

View File

@ -1,6 +1,7 @@
using GFramework.Core.command; using GFramework.Core.Abstractions.architecture;
using GFramework.Core.events; using GFramework.Core.Abstractions.command;
using GFramework.Core.query; using GFramework.Core.Abstractions.events;
using GFramework.Core.Abstractions.query;
namespace GFramework.Core.architecture; namespace GFramework.Core.architecture;

View File

@ -1,4 +1,7 @@
using GFramework.Core.events; using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.events;
using GFramework.Core.Abstractions.ioc;
using GFramework.Core.events;
using GFramework.Core.ioc; using GFramework.Core.ioc;
namespace GFramework.Core.architecture; namespace GFramework.Core.architecture;

View File

@ -1,4 +1,5 @@
using GFramework.Core.rule; using GFramework.Core.Abstractions.command;
using GFramework.Core.rule;
namespace GFramework.Core.command; namespace GFramework.Core.command;

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.events; using GFramework.Core.Abstractions.events;
namespace GFramework.Core.events;
/// <summary> /// <summary>
/// 默认注销器类,用于执行注销操作 /// 默认注销器类,用于执行注销操作

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.events; using GFramework.Core.Abstractions.events;
namespace GFramework.Core.events;
/// <summary> /// <summary>
/// 简单事件类,用于注册、注销和触发无参事件回调 /// 简单事件类,用于注册、注销和触发无参事件回调

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.events; using GFramework.Core.Abstractions.events;
namespace GFramework.Core.events;
/// <summary> /// <summary>
/// 泛型事件类,支持一个泛型参数 T 的事件注册、注销与触发。 /// 泛型事件类,支持一个泛型参数 T 的事件注册、注销与触发。

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.events; using GFramework.Core.Abstractions.events;
namespace GFramework.Core.events;
/// <summary> /// <summary>
/// EasyEvents事件管理器类用于全局事件的注册、获取和管理 /// EasyEvents事件管理器类用于全局事件的注册、获取和管理

View File

@ -1,3 +1,4 @@
using GFramework.Core.Abstractions.events;
using GFramework.Core.extensions; using GFramework.Core.extensions;
namespace GFramework.Core.events; namespace GFramework.Core.events;
@ -12,7 +13,7 @@ public class OrEvent : IUnRegisterList
/// <summary> /// <summary>
/// 获取取消注册列表 /// 获取取消注册列表
/// </summary> /// </summary>
public List<IUnRegister> UnregisterList { get; } = new(); public IList<IUnRegister> UnregisterList { get; }
/// <summary> /// <summary>
/// 将指定的事件与当前OrEvent进行或逻辑组合 /// 将指定的事件与当前OrEvent进行或逻辑组合

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.events; using GFramework.Core.Abstractions.events;
namespace GFramework.Core.events;
/// <summary> /// <summary>
/// 类型事件系统,提供基于类型的事件发送、注册和注销功能 /// 类型事件系统,提供基于类型的事件发送、注册和注销功能

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.events; using GFramework.Core.Abstractions.events;
namespace GFramework.Core.events;
/// <summary> /// <summary>
/// 取消注册列表类,用于管理多个需要取消注册的对象 /// 取消注册列表类,用于管理多个需要取消注册的对象
@ -10,7 +12,7 @@ public class UnRegisterList : IUnRegisterList
/// <summary> /// <summary>
/// 获取取消注册列表的只读属性 /// 获取取消注册列表的只读属性
/// </summary> /// </summary>
public List<IUnRegister> UnregisterList { get; } public IList<IUnRegister> UnregisterList { get; }
/// <summary> /// <summary>
/// 向取消注册列表中添加一个新的可取消注册对象 /// 向取消注册列表中添加一个新的可取消注册对象

View File

@ -1,4 +1,5 @@
using GFramework.Core.events; using GFramework.Core.Abstractions.events;
using GFramework.Core.events;
namespace GFramework.Core.extensions; namespace GFramework.Core.extensions;

View File

@ -1,4 +1,4 @@
using GFramework.Core.events; using GFramework.Core.Abstractions.events;
namespace GFramework.Core.extensions; namespace GFramework.Core.extensions;

View File

@ -1,6 +1,7 @@
using GFramework.Core.logging; using GFramework.Core.Abstractions.ioc;
using GFramework.Core.Abstractions.logging;
using GFramework.Core.Abstractions.system;
using GFramework.Core.rule; using GFramework.Core.rule;
using GFramework.Core.system;
namespace GFramework.Core.ioc; namespace GFramework.Core.ioc;

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.logging; using GFramework.Core.Abstractions.logging;
namespace GFramework.Core.logging;
/// <summary> /// <summary>
/// 日志抽象基类,封装日志级别判断、格式化与异常处理逻辑。 /// 日志抽象基类,封装日志级别判断、格式化与异常处理逻辑。

View File

@ -1,3 +1,5 @@
using GFramework.Core.Abstractions.logging;
namespace GFramework.Core.logging; namespace GFramework.Core.logging;
/// <summary> /// <summary>

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.logging; using GFramework.Core.Abstractions.logging;
namespace GFramework.Core.logging;
/// <summary> /// <summary>
/// 控制台日志提供程序,用于创建控制台日志记录器实例 /// 控制台日志提供程序,用于创建控制台日志记录器实例

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.logging; using GFramework.Core.Abstractions.logging;
namespace GFramework.Core.logging;
/// <summary> /// <summary>
/// 空操作日志记录器实现,不执行任何实际的日志记录操作 /// 空操作日志记录器实现,不执行任何实际的日志记录操作

View File

@ -1,4 +1,6 @@
namespace GFramework.Core.logging; using GFramework.Core.Abstractions.logging;
namespace GFramework.Core.logging;
/// <summary> /// <summary>
/// 无操作日志工厂实现,用于提供空的日志记录功能 /// 无操作日志工厂实现,用于提供空的日志记录功能

View File

@ -1,4 +1,5 @@
using GFramework.Core.architecture; using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.model;
namespace GFramework.Core.model; namespace GFramework.Core.model;

View File

@ -1,4 +1,5 @@
using GFramework.Core.events; using GFramework.Core.Abstractions.events;
using GFramework.Core.Abstractions.property;
namespace GFramework.Core.property; namespace GFramework.Core.property;
@ -48,6 +49,21 @@ public class BindableProperty<T>(T defaultValue = default!) : IBindableProperty<
MValue = newValue; MValue = newValue;
} }
/// <summary>
/// 实现IEasyEvent接口的注册方法将无参事件转换为有参事件处理
/// </summary>
/// <param name="onEvent">无参事件回调</param>
/// <returns>可用于取消注册的接口</returns>
IUnRegister IEasyEvent.Register(Action onEvent)
{
return Register(Action);
void Action(T _)
{
onEvent();
}
}
/// <summary> /// <summary>
/// 注册属性值变化事件回调 /// 注册属性值变化事件回调
/// </summary> /// </summary>
@ -79,21 +95,6 @@ public class BindableProperty<T>(T defaultValue = default!) : IBindableProperty<
_mOnValueChanged -= onValueChanged; _mOnValueChanged -= onValueChanged;
} }
/// <summary>
/// 实现IEasyEvent接口的注册方法将无参事件转换为有参事件处理
/// </summary>
/// <param name="onEvent">无参事件回调</param>
/// <returns>可用于取消注册的接口</returns>
IUnRegister IEasyEvent.Register(Action onEvent)
{
return Register(Action);
void Action(T _)
{
onEvent();
}
}
/// <summary> /// <summary>
/// 设置自定义比较器 /// 设置自定义比较器
/// </summary> /// </summary>

View File

@ -1,4 +1,4 @@
using GFramework.Core.events; using GFramework.Core.Abstractions.events;
namespace GFramework.Core.property; namespace GFramework.Core.property;

View File

@ -1,3 +1,4 @@
using GFramework.Core.Abstractions.query;
using GFramework.Core.rule; using GFramework.Core.rule;
namespace GFramework.Core.query; namespace GFramework.Core.query;

View File

@ -1,4 +1,5 @@
using GFramework.Core.architecture; using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.rule;
namespace GFramework.Core.rule; namespace GFramework.Core.rule;

View File

@ -1,4 +1,5 @@
using GFramework.Core.logging; using GFramework.Core.Abstractions.logging;
using GFramework.Core.Abstractions.system;
using GFramework.Core.rule; using GFramework.Core.rule;
namespace GFramework.Core.system; namespace GFramework.Core.system;

View File

@ -1,4 +1,5 @@
using GFramework.Core.logging; using GFramework.Core.Abstractions.logging;
using GFramework.Core.Abstractions.utility;
using GFramework.Core.rule; using GFramework.Core.rule;
namespace GFramework.Core.utility; namespace GFramework.Core.utility;

View File

@ -26,7 +26,7 @@
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<!-- Generator 编译期引用 Attributes / Common但不打包 --> <!-- Generator 编译期引用 Godot.SourceGenerators.Abstractions / Common但不打包 -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\GFramework.Godot.SourceGenerators.Abstractions\GFramework.Godot.SourceGenerators.Abstractions.csproj" PrivateAssets="all"/> <ProjectReference Include="..\GFramework.Godot.SourceGenerators.Abstractions\GFramework.Godot.SourceGenerators.Abstractions.csproj" PrivateAssets="all"/>
<ProjectReference Include="..\GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj" PrivateAssets="all"/> <ProjectReference Include="..\GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj" PrivateAssets="all"/>

View File

@ -8,6 +8,7 @@
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<MeziantouPolyfill_IncludedPolyfills>T:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute</MeziantouPolyfill_IncludedPolyfills> <MeziantouPolyfill_IncludedPolyfills>T:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute</MeziantouPolyfill_IncludedPolyfills>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<!-- 引入必要的命名空间 --> <!-- 引入必要的命名空间 -->
@ -16,6 +17,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.14.0" PrivateAssets="all"/> <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.14.0" PrivateAssets="all"/>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="4.14.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" PrivateAssets="all"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<AdditionalFiles Include="AnalyzerReleases.Shipped.md"/> <AdditionalFiles Include="AnalyzerReleases.Shipped.md"/>

View File

@ -24,6 +24,6 @@ public static class CommonDiagnostics
"Class '{0}' must be declared partial for code generation", "Class '{0}' must be declared partial for code generation",
"GFramework.Common", "GFramework.Common",
DiagnosticSeverity.Error, DiagnosticSeverity.Error,
true isEnabledByDefault: true
); );
} }

View File

@ -0,0 +1,173 @@
using System;
using System.Linq;
using GFramework.SourceGenerators.Common.diagnostics;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace GFramework.SourceGenerators.Common.generator;
/// <summary>
/// 属性类生成器基类,用于处理带有特定属性的类并生成相应的源代码
/// </summary>
public abstract class AttributeClassGeneratorBase : IIncrementalGenerator
{
/// <summary>
/// 获取属性的元数据名称
/// </summary>
protected abstract Type AttributeType { get; }
/// <summary>
/// Attribute 的短名称(不含 Attribute 后缀)
/// 仅用于 Syntax 层宽松匹配
/// </summary>
protected abstract string AttributeShortNameWithoutSuffix { get; }
/// <summary>
/// 初始化增量生成器
/// </summary>
/// <param name="context">增量生成器初始化上下文</param>
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var targets = context.SyntaxProvider.CreateSyntaxProvider(
predicate: (node, _) =>
node is ClassDeclarationSyntax cls &&
cls.AttributeLists
.SelectMany(a => a.Attributes)
.Any(a => a.Name.ToString()
.Contains(AttributeShortNameWithoutSuffix)),
transform: static (ctx, t) =>
{
var cls = (ClassDeclarationSyntax)ctx.Node;
var symbol = ctx.SemanticModel.GetDeclaredSymbol(cls, cancellationToken: t);
return (ClassDecl: cls, Symbol: symbol);
}
)
.Where(x => x.Symbol is not null);
context.RegisterSourceOutput(targets, (spc, pair) =>
{
try
{
Execute(spc, pair.ClassDecl, pair.Symbol!);
}
catch (Exception ex)
{
EmitError(spc, pair.Symbol, ex);
}
});
}
/// <summary>
/// 执行源代码生成的主要逻辑
/// </summary>
/// <param name="context">源生产上下文</param>
/// <param name="classDecl">类声明语法节点</param>
/// <param name="symbol">命名类型符号</param>
private void Execute(
SourceProductionContext context,
ClassDeclarationSyntax classDecl,
INamedTypeSymbol symbol)
{
var attr = GetAttribute(symbol);
if (attr == null) return;
// partial 校验
if (!classDecl.Modifiers.Any(SyntaxKind.PartialKeyword))
{
ReportClassMustBePartial(context, classDecl, symbol);
return;
}
// 子类校验
if (!ValidateSymbol(context, classDecl, symbol, attr))
return;
var source = Generate(symbol, attr);
context.AddSource(GetHintName(symbol), source);
}
#region
/// <summary>
/// 验证符号的有效性
/// </summary>
/// <param name="context">源生产上下文</param>
/// <param name="syntax">类声明语法节点</param>
/// <param name="symbol">命名类型符号</param>
/// <param name="attr">属性数据</param>
/// <returns>验证是否通过</returns>
protected virtual bool ValidateSymbol(
SourceProductionContext context,
ClassDeclarationSyntax syntax,
INamedTypeSymbol symbol,
AttributeData attr)
=> true;
/// <summary>
/// 生成源代码
/// </summary>
/// <param name="symbol">命名类型符号</param>
/// <param name="attr">属性数据</param>
/// <returns>生成的源代码字符串</returns>
protected abstract string Generate(
INamedTypeSymbol symbol,
AttributeData attr);
/// <summary>
/// 获取生成文件的提示名称
/// </summary>
/// <param name="symbol">命名类型符号</param>
/// <returns>生成文件的提示名称</returns>
protected virtual string GetHintName(INamedTypeSymbol symbol)
=> $"{symbol.Name}.g.cs";
#endregion
#region Attribute / Diagnostic
/// <summary>
/// 获取指定符号的属性数据
/// </summary>
/// <param name="symbol">命名类型符号</param>
/// <returns>属性数据如果未找到则返回null</returns>
protected virtual AttributeData? GetAttribute(INamedTypeSymbol symbol)
=> symbol.GetAttributes().FirstOrDefault(a =>
string.Equals(a.AttributeClass?.ToDisplayString(), AttributeType.FullName, StringComparison.Ordinal));
/// <summary>
/// 报告类必须是partial的诊断信息
/// </summary>
/// <param name="context">源生产上下文</param>
/// <param name="syntax">类声明语法节点</param>
/// <param name="symbol">命名类型符号</param>
protected virtual void ReportClassMustBePartial(
SourceProductionContext context,
ClassDeclarationSyntax syntax,
INamedTypeSymbol symbol)
{
context.ReportDiagnostic(Diagnostic.Create(
CommonDiagnostics.ClassMustBePartial,
syntax.Identifier.GetLocation(),
symbol.Name));
}
/// <summary>
/// 发出错误信息
/// </summary>
/// <param name="context">源生产上下文</param>
/// <param name="symbol">命名类型符号</param>
/// <param name="ex">异常对象</param>
protected virtual void EmitError(
SourceProductionContext context,
INamedTypeSymbol? symbol,
Exception ex)
{
var name = symbol?.Name ?? "Unknown";
var text =
$"// source generator error: {ex.Message}\n// {ex.StackTrace}";
context.AddSource($"{name}.Error.g.cs", text);
}
#endregion
}

View File

@ -26,10 +26,11 @@
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<!-- Generator 编译期引用 Attributes / Common,但不打包 --> <!-- Generator 编译期引用 SourceGenerators.Abstractions / Common / Core.Abstractions,但不打包 -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\GFramework.SourceGenerators.Abstractions\GFramework.SourceGenerators.Abstractions.csproj" PrivateAssets="all"/> <ProjectReference Include="..\GFramework.SourceGenerators.Abstractions\GFramework.SourceGenerators.Abstractions.csproj" PrivateAssets="all"/>
<ProjectReference Include="..\GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj" PrivateAssets="all"/> <ProjectReference Include="..\GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj" PrivateAssets="all"/>
<ProjectReference Include="..\GFramework.Core.Abstractions\GFramework.Core.Abstractions.csproj" PrivateAssets="all"/>
</ItemGroup> </ItemGroup>
<!-- ★关键:只把 Generator DLL 放进 analyzers --> <!-- ★关键:只把 Generator DLL 放进 analyzers -->

View File

@ -1,102 +1,60 @@
using System.Linq; using System;
using System.Linq;
using System.Text; using System.Text;
using GFramework.SourceGenerators.Common.diagnostics; using GFramework.SourceGenerators.Abstractions.rule;
using GFramework.SourceGenerators.constants; using GFramework.SourceGenerators.Common.generator;
using GFramework.SourceGenerators.diagnostics; using GFramework.SourceGenerators.diagnostics;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace GFramework.SourceGenerators.rule; namespace GFramework.SourceGenerators.rule;
[Generator] [Generator]
public sealed class ContextAwareGenerator : IIncrementalGenerator public sealed class ContextAwareGenerator : AttributeClassGeneratorBase
{ {
private const string AttributeMetadataName = /// <summary>
$"{PathContests.RootAbstractionsPath}.rule.ContextAwareAttribute"; /// 使用强类型 Attribute替代字符串
/// </summary>
protected override Type AttributeType => typeof(ContextAwareAttribute);
public void Initialize(IncrementalGeneratorInitializationContext context) /// <summary>
/// 仅用于 Syntax 粗筛选
/// </summary>
protected override string AttributeShortNameWithoutSuffix => "ContextAware";
/// <summary>
/// 额外语义校验:必须实现 IContextAware
/// </summary>
protected override bool ValidateSymbol(
SourceProductionContext context,
ClassDeclarationSyntax syntax,
INamedTypeSymbol symbol,
AttributeData attr)
{ {
// 1⃣ 查找候选类 if (!symbol.AllInterfaces.Any(i =>
var candidates = context.SyntaxProvider i.ToDisplayString() == typeof(IContextAware).FullName))
.CreateSyntaxProvider(
predicate: static (node, _) => node is ClassDeclarationSyntax,
transform: static (ctx, _) => GetCandidate(ctx)
)
.Where(static s => s is not null);
// 2⃣ 注册生成输出
context.RegisterSourceOutput(candidates, static (spc, symbol) =>
{
if (symbol != null)
GenerateOutput(spc, symbol);
});
}
#region
private static INamedTypeSymbol? GetCandidate(GeneratorSyntaxContext context)
{
if (context.SemanticModel.GetDeclaredSymbol(context.Node) is not INamedTypeSymbol symbol)
return null;
// 仅筛选带有 ContextAwareAttribute 的类
var hasAttr = symbol.GetAttributes()
.Any(attr => attr.AttributeClass?.ToDisplayString() == AttributeMetadataName);
return hasAttr ? symbol : null;
}
#endregion
#region +
private static void GenerateOutput(SourceProductionContext context, INamedTypeSymbol symbol)
{
var syntax = symbol.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax() as ClassDeclarationSyntax;
if (syntax == null)
return;
// 1⃣ 必须是 partial
if (!syntax.Modifiers.Any(SyntaxKind.PartialKeyword))
{
context.ReportDiagnostic(Diagnostic.Create(
CommonDiagnostics.ClassMustBePartial,
syntax.Identifier.GetLocation(),
symbol.Name
));
return;
}
// 2⃣ 必须实现 IContextAware直接或间接
if (!symbol.AllInterfaces.Any(i => i.ToDisplayString() == "GFramework.Core.rule.IContextAware"))
{ {
context.ReportDiagnostic(Diagnostic.Create( context.ReportDiagnostic(Diagnostic.Create(
ContextAwareDiagnostic.ClassMustImplementIContextAware, ContextAwareDiagnostic.ClassMustImplementIContextAware,
syntax.Identifier.GetLocation(), syntax.Identifier.GetLocation(),
symbol.Name symbol.Name));
)); return false;
return;
} }
// 3⃣ 生成源码 return true;
}
/// <summary>
/// 生成源码
/// </summary>
protected override string Generate(
INamedTypeSymbol symbol,
AttributeData attr)
{
var ns = symbol.ContainingNamespace.IsGlobalNamespace var ns = symbol.ContainingNamespace.IsGlobalNamespace
? null ? null
: symbol.ContainingNamespace.ToDisplayString(); : symbol.ContainingNamespace.ToDisplayString();
var source = GenerateSource(ns, symbol);
context
.AddSource(
$"{symbol.Name}.ContextAware.g.cs",
source);
}
#endregion
#region
private static string GenerateSource(string? ns, INamedTypeSymbol symbol)
{
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine("// <auto-generated/>"); sb.AppendLine("// <auto-generated/>");
sb.AppendLine("#nullable enable"); sb.AppendLine("#nullable enable");
@ -121,5 +79,9 @@ public sealed class ContextAwareGenerator : IIncrementalGenerator
return sb.ToString().TrimEnd(); return sb.ToString().TrimEnd();
} }
#endregion /// <summary>
/// 自定义生成文件名
/// </summary>
protected override string GetHintName(INamedTypeSymbol symbol)
=> $"{symbol.Name}.ContextAware.g.cs";
} }

View File

@ -43,6 +43,7 @@
<None Remove="GFramework.SourceGenerators.Tests\**"/> <None Remove="GFramework.SourceGenerators.Tests\**"/>
<None Remove="GFramework.Godot.SourceGenerators.Abstractions\**"/> <None Remove="GFramework.Godot.SourceGenerators.Abstractions\**"/>
<None Remove="GFramework.SourceGenerators.Abstractions\**"/> <None Remove="GFramework.SourceGenerators.Abstractions\**"/>
<None Remove="GFramework.Core.Abstractions\**"/>
</ItemGroup> </ItemGroup>
<!-- 聚合核心模块 --> <!-- 聚合核心模块 -->
<ItemGroup> <ItemGroup>
@ -69,6 +70,7 @@
<Compile Remove="GFramework.SourceGenerators.Tests\**"/> <Compile Remove="GFramework.SourceGenerators.Tests\**"/>
<Compile Remove="GFramework.Godot.SourceGenerators.Abstractions\**"/> <Compile Remove="GFramework.Godot.SourceGenerators.Abstractions\**"/>
<Compile Remove="GFramework.SourceGenerators.Abstractions\**"/> <Compile Remove="GFramework.SourceGenerators.Abstractions\**"/>
<Compile Remove="GFramework.Core.Abstractions\**"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Remove="GFramework.Core\**"/> <EmbeddedResource Remove="GFramework.Core\**"/>
@ -81,6 +83,7 @@
<EmbeddedResource Remove="GFramework.SourceGenerators.Tests\**"/> <EmbeddedResource Remove="GFramework.SourceGenerators.Tests\**"/>
<EmbeddedResource Remove="GFramework.Godot.SourceGenerators.Abstractions\**"/> <EmbeddedResource Remove="GFramework.Godot.SourceGenerators.Abstractions\**"/>
<EmbeddedResource Remove="GFramework.SourceGenerators.Abstractions\**"/> <EmbeddedResource Remove="GFramework.SourceGenerators.Abstractions\**"/>
<EmbeddedResource Remove="GFramework.Core.Abstractions\**"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.14.0"/> <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.14.0"/>

View File

@ -20,6 +20,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.SourceGenerators
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.SourceGenerators.Common", "GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj", "{B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.SourceGenerators.Common", "GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj", "{B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Core.Abstractions", "GFramework.Core.Abstractions\GFramework.Core.Abstractions.csproj", "{31BA9F62-153A-4943-A8A0-7571FC7D5FEE}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -66,5 +68,9 @@ Global
{B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Debug|Any CPU.Build.0 = Debug|Any CPU {B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Release|Any CPU.ActiveCfg = Release|Any CPU {B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Release|Any CPU.Build.0 = Release|Any CPU {B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Release|Any CPU.Build.0 = Release|Any CPU
{31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal