mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-12 22:03:30 +08:00
docs: 添加 CQRS 架构模式和游戏配置系统文档
- 新增 CQRS 核心概念、命令查询处理器实现指南 - 添加 CQRS 高级用法包括通知发布、管道行为和流式处理 - 提供 CQRS 最佳实践和常见问题解决方案 - 添加游戏配置系统完整接入模板和运行时读取示例 - 包含 YAML 配置文件和 JSON Schema 结构定义说明 - 提供 Godot 引擎配置桥接和热重载功能使用指南 - 添加架构模块集成和生成查询辅助功能文档
This commit is contained in:
parent
d8831733ff
commit
09f751a4f7
@ -73,9 +73,8 @@ Architecture 负责统一生命周期编排,核心阶段包括:
|
|||||||
|
|
||||||
### CQRS
|
### CQRS
|
||||||
|
|
||||||
命令与查询分离,支持同步与异步执行。当前版本内建自有 CQRS runtime、行为管道和 handler 自动注册;公开 API 里仍保留少量历史
|
命令与查询分离,支持同步与异步执行。当前版本内建自有 CQRS runtime、行为管道和 handler 自动注册;历史 `Mediator`
|
||||||
`Mediator` 命名以兼容旧调用点,但这些别名已进入正式弃用周期:新代码应使用 `Cqrs` 命名入口,旧别名会继续兼容一段时间并计划在未来
|
兼容别名已从公开 API 移除,统一使用 `Cqrs` 命名入口。
|
||||||
major 版本中移除。
|
|
||||||
|
|
||||||
### EventBus
|
### EventBus
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using GFramework.Core.Abstractions.Lifecycle;
|
using GFramework.Core.Abstractions.Lifecycle;
|
||||||
using GFramework.Core.Abstractions.Model;
|
using GFramework.Core.Abstractions.Model;
|
||||||
@ -82,20 +81,6 @@ public interface IArchitecture : IAsyncInitializable, IAsyncDestroyable, IInitia
|
|||||||
void RegisterCqrsPipelineBehavior<TBehavior>()
|
void RegisterCqrsPipelineBehavior<TBehavior>()
|
||||||
where TBehavior : class;
|
where TBehavior : class;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 注册 CQRS 请求管道行为。
|
|
||||||
/// 该成员保留旧名称以兼容历史调用点,内部行为与 <see cref="RegisterCqrsPipelineBehavior{TBehavior}" /> 一致。
|
|
||||||
/// 新代码不应继续依赖该别名;兼容层计划在未来的 major 版本中移除。
|
|
||||||
/// 既支持实现 <c>IPipelineBehavior<,></c> 的开放泛型行为类型,
|
|
||||||
/// 也支持绑定到单一请求/响应对的封闭行为类型。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TBehavior">行为类型,必须是引用类型</typeparam>
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
[Obsolete(
|
|
||||||
"Use RegisterCqrsPipelineBehavior<TBehavior>() instead. This compatibility alias will be removed in a future major version.")]
|
|
||||||
void RegisterMediatorBehavior<TBehavior>()
|
|
||||||
where TBehavior : class;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 从指定程序集显式注册 CQRS 处理器。
|
/// 从指定程序集显式注册 CQRS 处理器。
|
||||||
/// 当处理器位于默认架构程序集之外的模块或扩展程序集中时,可在初始化阶段调用该入口接入对应程序集。
|
/// 当处理器位于默认架构程序集之外的模块或扩展程序集中时,可在初始化阶段调用该入口接入对应程序集。
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System.ComponentModel;
|
using System.Reflection;
|
||||||
using System.Reflection;
|
|
||||||
using GFramework.Core.Abstractions.Rule;
|
using GFramework.Core.Abstractions.Rule;
|
||||||
using GFramework.Core.Abstractions.Systems;
|
using GFramework.Core.Abstractions.Systems;
|
||||||
|
|
||||||
@ -97,18 +96,6 @@ public interface IIocContainer : IContextAware
|
|||||||
void RegisterCqrsPipelineBehavior<TBehavior>()
|
void RegisterCqrsPipelineBehavior<TBehavior>()
|
||||||
where TBehavior : class;
|
where TBehavior : class;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 注册 CQRS 请求管道行为。
|
|
||||||
/// 该成员保留旧名称以兼容历史调用点,内部行为与 <see cref="RegisterCqrsPipelineBehavior{TBehavior}" /> 一致。
|
|
||||||
/// 新代码不应继续依赖该别名;兼容层计划在未来的 major 版本中移除。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TBehavior">行为类型,必须是引用类型</typeparam>
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
[Obsolete(
|
|
||||||
"Use RegisterCqrsPipelineBehavior<TBehavior>() instead. This compatibility alias will be removed in a future major version.")]
|
|
||||||
void RegisterMediatorBehavior<TBehavior>()
|
|
||||||
where TBehavior : class;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 从指定程序集显式注册 CQRS 处理器。
|
/// 从指定程序集显式注册 CQRS 处理器。
|
||||||
/// 该入口适用于处理器不位于默认架构程序集中的场景,例如扩展包、模块程序集或拆分后的业务程序集。
|
/// 该入口适用于处理器不位于默认架构程序集中的场景,例如扩展包、模块程序集或拆分后的业务程序集。
|
||||||
|
|||||||
@ -18,16 +18,6 @@
|
|||||||
GF_ContextRegistration_001 | GFramework.SourceGenerators.rule | Warning | ContextRegistrationDiagnostics
|
GF_ContextRegistration_001 | GFramework.SourceGenerators.rule | Warning | ContextRegistrationDiagnostics
|
||||||
GF_ContextRegistration_002 | GFramework.SourceGenerators.rule | Warning | ContextRegistrationDiagnostics
|
GF_ContextRegistration_002 | GFramework.SourceGenerators.rule | Warning | ContextRegistrationDiagnostics
|
||||||
GF_ContextRegistration_003 | GFramework.SourceGenerators.rule | Warning | ContextRegistrationDiagnostics
|
GF_ContextRegistration_003 | GFramework.SourceGenerators.rule | Warning | ContextRegistrationDiagnostics
|
||||||
GF_ConfigSchema_001 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
|
||||||
GF_ConfigSchema_002 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
|
||||||
GF_ConfigSchema_003 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
|
||||||
GF_ConfigSchema_004 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
|
||||||
GF_ConfigSchema_005 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
|
||||||
GF_ConfigSchema_006 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
|
||||||
GF_ConfigSchema_007 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
|
||||||
GF_ConfigSchema_008 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
|
||||||
GF_ConfigSchema_009 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
|
||||||
GF_ConfigSchema_010 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
|
||||||
GF_AutoModule_001 | GFramework.SourceGenerators.Architecture | Error | AutoRegisterModuleDiagnostics
|
GF_AutoModule_001 | GFramework.SourceGenerators.Architecture | Error | AutoRegisterModuleDiagnostics
|
||||||
GF_AutoModule_002 | GFramework.SourceGenerators.Architecture | Error | AutoRegisterModuleDiagnostics
|
GF_AutoModule_002 | GFramework.SourceGenerators.Architecture | Error | AutoRegisterModuleDiagnostics
|
||||||
GF_AutoModule_003 | GFramework.SourceGenerators.Architecture | Error | AutoRegisterModuleDiagnostics
|
GF_AutoModule_003 | GFramework.SourceGenerators.Architecture | Error | AutoRegisterModuleDiagnostics
|
||||||
@ -1,4 +1,3 @@
|
|||||||
using System.Collections.Immutable;
|
|
||||||
using GFramework.SourceGenerators.Common.Constants;
|
using GFramework.SourceGenerators.Common.Constants;
|
||||||
using GFramework.SourceGenerators.Diagnostics;
|
using GFramework.SourceGenerators.Diagnostics;
|
||||||
using Microsoft.CodeAnalysis.Diagnostics;
|
using Microsoft.CodeAnalysis.Diagnostics;
|
||||||
@ -12,6 +11,17 @@ namespace GFramework.SourceGenerators.Analyzers;
|
|||||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||||
public sealed class ContextRegistrationAnalyzer : DiagnosticAnalyzer
|
public sealed class ContextRegistrationAnalyzer : DiagnosticAnalyzer
|
||||||
{
|
{
|
||||||
|
private static readonly IReadOnlyDictionary<string, ComponentKind> _contextAwareBindingNames =
|
||||||
|
new Dictionary<string, ComponentKind>(StringComparer.Ordinal)
|
||||||
|
{
|
||||||
|
["GetModel"] = ComponentKind.Model,
|
||||||
|
["GetModels"] = ComponentKind.Model,
|
||||||
|
["GetSystem"] = ComponentKind.System,
|
||||||
|
["GetSystems"] = ComponentKind.System,
|
||||||
|
["GetUtility"] = ComponentKind.Utility,
|
||||||
|
["GetUtilities"] = ComponentKind.Utility
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前分析器支持的诊断规则。
|
/// 当前分析器支持的诊断规则。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -58,10 +68,12 @@ public sealed class ContextRegistrationAnalyzer : DiagnosticAnalyzer
|
|||||||
if (context.Node is not VariableDeclaratorSyntax variableDeclarator)
|
if (context.Node is not VariableDeclaratorSyntax variableDeclarator)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (context.SemanticModel.GetDeclaredSymbol(variableDeclarator, context.CancellationToken) is not IFieldSymbol fieldSymbol)
|
if (context.SemanticModel.GetDeclaredSymbol(variableDeclarator, context.CancellationToken) is not IFieldSymbol
|
||||||
|
fieldSymbol)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TryCreateBindingRequest(fieldSymbol, variableDeclarator.Identifier.GetLocation(), symbols, out var request))
|
if (!TryCreateBindingRequest(fieldSymbol, variableDeclarator.Identifier.GetLocation(), symbols,
|
||||||
|
out var request))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ReportMissingRegistration(context, registrationIndex, request);
|
ReportMissingRegistration(context, registrationIndex, request);
|
||||||
@ -272,17 +284,6 @@ public sealed class ContextRegistrationAnalyzer : DiagnosticAnalyzer
|
|||||||
return namedType.TypeArguments[0] as INamedTypeSymbol;
|
return namedType.TypeArguments[0] as INamedTypeSymbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly IReadOnlyDictionary<string, ComponentKind> _contextAwareBindingNames =
|
|
||||||
new Dictionary<string, ComponentKind>(StringComparer.Ordinal)
|
|
||||||
{
|
|
||||||
["GetModel"] = ComponentKind.Model,
|
|
||||||
["GetModels"] = ComponentKind.Model,
|
|
||||||
["GetSystem"] = ComponentKind.System,
|
|
||||||
["GetSystems"] = ComponentKind.System,
|
|
||||||
["GetUtility"] = ComponentKind.Utility,
|
|
||||||
["GetUtilities"] = ComponentKind.Utility
|
|
||||||
};
|
|
||||||
|
|
||||||
private enum ComponentKind
|
private enum ComponentKind
|
||||||
{
|
{
|
||||||
Model,
|
Model,
|
||||||
@ -368,22 +369,35 @@ public sealed class ContextRegistrationAnalyzer : DiagnosticAnalyzer
|
|||||||
{
|
{
|
||||||
return new SymbolCache(
|
return new SymbolCache(
|
||||||
compilation.GetTypeByMetadataName($"{PathContests.CoreNamespace}.Architectures.Architecture"),
|
compilation.GetTypeByMetadataName($"{PathContests.CoreNamespace}.Architectures.Architecture"),
|
||||||
compilation.GetTypeByMetadataName($"{PathContests.CoreAbstractionsNamespace}.Architectures.IArchitecture"),
|
compilation.GetTypeByMetadataName(
|
||||||
compilation.GetTypeByMetadataName($"{PathContests.CoreAbstractionsNamespace}.Architectures.IArchitectureModule"),
|
$"{PathContests.CoreAbstractionsNamespace}.Architectures.IArchitecture"),
|
||||||
compilation.GetTypeByMetadataName($"{PathContests.CoreAbstractionsNamespace}.Architectures.IArchitectureContext"),
|
compilation.GetTypeByMetadataName(
|
||||||
|
$"{PathContests.CoreAbstractionsNamespace}.Architectures.IArchitectureModule"),
|
||||||
|
compilation.GetTypeByMetadataName(
|
||||||
|
$"{PathContests.CoreAbstractionsNamespace}.Architectures.IArchitectureContext"),
|
||||||
compilation.GetTypeByMetadataName("System.Collections.Generic.IReadOnlyList`1"),
|
compilation.GetTypeByMetadataName("System.Collections.Generic.IReadOnlyList`1"),
|
||||||
compilation.GetTypeByMetadataName($"{PathContests.CoreNamespace}.Extensions.ContextAwareServiceExtensions"),
|
compilation.GetTypeByMetadataName(
|
||||||
compilation.GetTypeByMetadataName($"{PathContests.SourceGeneratorsAbstractionsPath}.Rule.GetModelAttribute"),
|
$"{PathContests.CoreNamespace}.Extensions.ContextAwareServiceExtensions"),
|
||||||
compilation.GetTypeByMetadataName($"{PathContests.SourceGeneratorsAbstractionsPath}.Rule.GetModelsAttribute"),
|
compilation.GetTypeByMetadataName(
|
||||||
compilation.GetTypeByMetadataName($"{PathContests.SourceGeneratorsAbstractionsPath}.Rule.GetSystemAttribute"),
|
$"{PathContests.SourceGeneratorsAbstractionsPath}.Rule.GetModelAttribute"),
|
||||||
compilation.GetTypeByMetadataName($"{PathContests.SourceGeneratorsAbstractionsPath}.Rule.GetSystemsAttribute"),
|
compilation.GetTypeByMetadataName(
|
||||||
compilation.GetTypeByMetadataName($"{PathContests.SourceGeneratorsAbstractionsPath}.Rule.GetUtilityAttribute"),
|
$"{PathContests.SourceGeneratorsAbstractionsPath}.Rule.GetModelsAttribute"),
|
||||||
compilation.GetTypeByMetadataName($"{PathContests.SourceGeneratorsAbstractionsPath}.Rule.GetUtilitiesAttribute"));
|
compilation.GetTypeByMetadataName(
|
||||||
|
$"{PathContests.SourceGeneratorsAbstractionsPath}.Rule.GetSystemAttribute"),
|
||||||
|
compilation.GetTypeByMetadataName(
|
||||||
|
$"{PathContests.SourceGeneratorsAbstractionsPath}.Rule.GetSystemsAttribute"),
|
||||||
|
compilation.GetTypeByMetadataName(
|
||||||
|
$"{PathContests.SourceGeneratorsAbstractionsPath}.Rule.GetUtilityAttribute"),
|
||||||
|
compilation.GetTypeByMetadataName(
|
||||||
|
$"{PathContests.SourceGeneratorsAbstractionsPath}.Rule.GetUtilitiesAttribute"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class RegistrationIndex
|
private sealed class RegistrationIndex
|
||||||
{
|
{
|
||||||
|
private readonly Compilation _compilation;
|
||||||
|
private readonly IReadOnlyDictionary<INamedTypeSymbol, ArchitectureRegistrationData> _registrations;
|
||||||
|
|
||||||
private RegistrationIndex(
|
private RegistrationIndex(
|
||||||
Compilation compilation,
|
Compilation compilation,
|
||||||
IReadOnlyDictionary<INamedTypeSymbol, ArchitectureRegistrationData> registrations)
|
IReadOnlyDictionary<INamedTypeSymbol, ArchitectureRegistrationData> registrations)
|
||||||
@ -392,14 +406,12 @@ public sealed class ContextRegistrationAnalyzer : DiagnosticAnalyzer
|
|||||||
_registrations = registrations;
|
_registrations = registrations;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Compilation _compilation;
|
|
||||||
private readonly IReadOnlyDictionary<INamedTypeSymbol, ArchitectureRegistrationData> _registrations;
|
|
||||||
|
|
||||||
public static RegistrationIndex Build(
|
public static RegistrationIndex Build(
|
||||||
Compilation compilation,
|
Compilation compilation,
|
||||||
SymbolCache symbols)
|
SymbolCache symbols)
|
||||||
{
|
{
|
||||||
var registrations = new Dictionary<INamedTypeSymbol, ArchitectureRegistrationData>(SymbolEqualityComparer.Default);
|
var registrations =
|
||||||
|
new Dictionary<INamedTypeSymbol, ArchitectureRegistrationData>(SymbolEqualityComparer.Default);
|
||||||
|
|
||||||
foreach (var type in SymbolHelpers.EnumerateNamedTypes(compilation.Assembly.GlobalNamespace))
|
foreach (var type in SymbolHelpers.EnumerateNamedTypes(compilation.Assembly.GlobalNamespace))
|
||||||
{
|
{
|
||||||
@ -690,7 +702,8 @@ public sealed class ContextRegistrationAnalyzer : DiagnosticAnalyzer
|
|||||||
return helperMethod.DeclaringSyntaxReferences.Length > 0;
|
return helperMethod.DeclaringSyntaxReferences.Length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
helperMethod = SymbolHelpers.ResolveHierarchyMethodImplementation(targetMethod, concreteType) ?? targetMethod;
|
helperMethod = SymbolHelpers.ResolveHierarchyMethodImplementation(targetMethod, concreteType) ??
|
||||||
|
targetMethod;
|
||||||
return helperMethod.DeclaringSyntaxReferences.Length > 0;
|
return helperMethod.DeclaringSyntaxReferences.Length > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -813,9 +826,12 @@ public sealed class ContextRegistrationAnalyzer : DiagnosticAnalyzer
|
|||||||
if (SymbolEqualityComparer.Default.Equals(candidate.OriginalDefinition, method.OriginalDefinition))
|
if (SymbolEqualityComparer.Default.Equals(candidate.OriginalDefinition, method.OriginalDefinition))
|
||||||
return candidate;
|
return candidate;
|
||||||
|
|
||||||
for (var overridden = candidate.OverriddenMethod; overridden != null; overridden = overridden.OverriddenMethod)
|
for (var overridden = candidate.OverriddenMethod;
|
||||||
|
overridden != null;
|
||||||
|
overridden = overridden.OverriddenMethod)
|
||||||
{
|
{
|
||||||
if (SymbolEqualityComparer.Default.Equals(overridden.OriginalDefinition, method.OriginalDefinition))
|
if (SymbolEqualityComparer.Default.Equals(overridden.OriginalDefinition,
|
||||||
|
method.OriginalDefinition))
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,6 +1,4 @@
|
|||||||
using System.Collections.Immutable;
|
|
||||||
using GFramework.SourceGenerators.Diagnostics;
|
using GFramework.SourceGenerators.Diagnostics;
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
using Microsoft.CodeAnalysis.Diagnostics;
|
using Microsoft.CodeAnalysis.Diagnostics;
|
||||||
using Microsoft.CodeAnalysis.Operations;
|
using Microsoft.CodeAnalysis.Operations;
|
||||||
|
|
||||||
@ -1,10 +1,6 @@
|
|||||||
using System.Text;
|
|
||||||
using GFramework.SourceGenerators.Common.Constants;
|
using GFramework.SourceGenerators.Common.Constants;
|
||||||
using GFramework.SourceGenerators.Common.Generator;
|
using GFramework.SourceGenerators.Common.Generator;
|
||||||
using GFramework.SourceGenerators.Diagnostics;
|
using GFramework.SourceGenerators.Diagnostics;
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
using Microsoft.CodeAnalysis.CSharp;
|
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
||||||
|
|
||||||
namespace GFramework.SourceGenerators.Bases;
|
namespace GFramework.SourceGenerators.Bases;
|
||||||
|
|
||||||
@ -1,6 +1,4 @@
|
|||||||
using Microsoft.CodeAnalysis;
|
namespace GFramework.SourceGenerators.Diagnostics;
|
||||||
|
|
||||||
namespace GFramework.SourceGenerators.Diagnostics;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 提供与上下文感知相关的诊断规则定义
|
/// 提供与上下文感知相关的诊断规则定义
|
||||||
@ -1,6 +1,4 @@
|
|||||||
using Microsoft.CodeAnalysis;
|
namespace GFramework.SourceGenerators.Diagnostics;
|
||||||
|
|
||||||
namespace GFramework.SourceGenerators.Diagnostics;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 提供诊断描述符的静态类,用于GFramework日志生成器的编译时检查
|
/// 提供诊断描述符的静态类,用于GFramework日志生成器的编译时检查
|
||||||
@ -1,5 +1,3 @@
|
|||||||
using Microsoft.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace GFramework.SourceGenerators.Diagnostics;
|
namespace GFramework.SourceGenerators.Diagnostics;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1,9 +1,6 @@
|
|||||||
using System.Text;
|
using GFramework.SourceGenerators.Common.Constants;
|
||||||
using GFramework.SourceGenerators.Common.Constants;
|
|
||||||
using GFramework.SourceGenerators.Common.Diagnostics;
|
using GFramework.SourceGenerators.Common.Diagnostics;
|
||||||
using GFramework.SourceGenerators.Common.Generator;
|
using GFramework.SourceGenerators.Common.Generator;
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
||||||
|
|
||||||
namespace GFramework.SourceGenerators.Enums;
|
namespace GFramework.SourceGenerators.Enums;
|
||||||
|
|
||||||
@ -30,7 +30,7 @@
|
|||||||
<!-- Generator 编译期引用 SourceGenerators.Abstractions / Common / Core.Abstractions,但不打包 -->
|
<!-- Generator 编译期引用 SourceGenerators.Abstractions / Common / Core.Abstractions,但不打包 -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\$(AssemblyName).Abstractions\$(AssemblyName).Abstractions.csproj" PrivateAssets="all"/>
|
<ProjectReference Include="..\$(AssemblyName).Abstractions\$(AssemblyName).Abstractions.csproj" PrivateAssets="all"/>
|
||||||
<ProjectReference Include="..\$(AssemblyName).Common\$(AssemblyName).Common.csproj" PrivateAssets="all"/>
|
<ProjectReference Include="..\GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj" PrivateAssets="all"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -63,6 +63,6 @@
|
|||||||
<None Include="$(OutputPath)\$(AssemblyName).Abstractions.xml" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
|
<None Include="$(OutputPath)\$(AssemblyName).Abstractions.xml" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
|
||||||
<None Include="$(OutputPath)\$(AssemblyName).Common.dll" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
|
<None Include="$(OutputPath)\$(AssemblyName).Common.dll" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
|
||||||
<None Include="$(OutputPath)\$(AssemblyName).Common.xml" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
|
<None Include="$(OutputPath)\$(AssemblyName).Common.xml" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
|
||||||
<None Include="GeWuYou.$(AssemblyName).targets" Pack="true" PackagePath="build" Visible="false"/>
|
<None Include="GeWuYou.GFramework.Core.SourceGenerators.targets" Pack="true" PackagePath="build" Visible="false"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Analyzer Include="$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.Core.SourceGenerators.dll"
|
||||||
|
Condition="Exists('$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.Core.SourceGenerators.dll')"/>
|
||||||
|
<Analyzer Include="$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.Core.SourceGenerators.Abstractions.dll"
|
||||||
|
Condition="Exists('$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.Core.SourceGenerators.Abstractions.dll')"/>
|
||||||
|
<Analyzer Include="$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.SourceGenerators.Common.dll"
|
||||||
|
Condition="Exists('$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.SourceGenerators.Common.dll')"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="EnsureGFrameworkCoreAnalyzers" BeforeTargets="CoreCompile">
|
||||||
|
<Message Text="Loading GFramework.Core source generators" Importance="high"/>
|
||||||
|
</Target>
|
||||||
|
</Project>
|
||||||
@ -1,10 +1,7 @@
|
|||||||
using System.Text;
|
using GFramework.SourceGenerators.Abstractions.Logging;
|
||||||
using GFramework.SourceGenerators.Abstractions.Logging;
|
|
||||||
using GFramework.SourceGenerators.Common.Constants;
|
using GFramework.SourceGenerators.Common.Constants;
|
||||||
using GFramework.SourceGenerators.Common.Extensions;
|
using GFramework.SourceGenerators.Common.Extensions;
|
||||||
using GFramework.SourceGenerators.Common.Generator;
|
using GFramework.SourceGenerators.Common.Generator;
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
||||||
|
|
||||||
namespace GFramework.SourceGenerators.Logging;
|
namespace GFramework.SourceGenerators.Logging;
|
||||||
|
|
||||||
@ -1,11 +1,7 @@
|
|||||||
using System.Text;
|
using GFramework.SourceGenerators.Common.Constants;
|
||||||
using GFramework.SourceGenerators.Common.Constants;
|
|
||||||
using GFramework.SourceGenerators.Common.Diagnostics;
|
using GFramework.SourceGenerators.Common.Diagnostics;
|
||||||
using GFramework.SourceGenerators.Common.Generator;
|
using GFramework.SourceGenerators.Common.Generator;
|
||||||
using GFramework.SourceGenerators.Diagnostics;
|
using GFramework.SourceGenerators.Diagnostics;
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
using Microsoft.CodeAnalysis.CSharp;
|
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
||||||
|
|
||||||
namespace GFramework.SourceGenerators.Rule;
|
namespace GFramework.SourceGenerators.Rule;
|
||||||
|
|
||||||
@ -1,4 +1,3 @@
|
|||||||
using System.Text;
|
|
||||||
using GFramework.SourceGenerators.Common.Constants;
|
using GFramework.SourceGenerators.Common.Constants;
|
||||||
using GFramework.SourceGenerators.Common.Diagnostics;
|
using GFramework.SourceGenerators.Common.Diagnostics;
|
||||||
using GFramework.SourceGenerators.Common.Extensions;
|
using GFramework.SourceGenerators.Common.Extensions;
|
||||||
@ -78,28 +78,6 @@ public class ArchitectureModulesBehaviorTests
|
|||||||
await architecture.DestroyAsync();
|
await architecture.DestroyAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 验证兼容别名 <c>RegisterMediatorBehavior</c> 仍会把 CQRS 行为接入请求管道。
|
|
||||||
/// </summary>
|
|
||||||
[Test]
|
|
||||||
public async Task RegisterMediatorBehavior_Should_Apply_Pipeline_Behavior_To_Request()
|
|
||||||
{
|
|
||||||
var architecture = new ModuleTestArchitecture(target =>
|
|
||||||
target.RegisterMediatorBehavior<TrackingPipelineBehavior<ModuleBehaviorRequest, string>>());
|
|
||||||
|
|
||||||
await architecture.InitializeAsync();
|
|
||||||
|
|
||||||
var response = await architecture.Context.SendRequestAsync(new ModuleBehaviorRequest());
|
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
|
||||||
{
|
|
||||||
Assert.That(response, Is.EqualTo("handled"));
|
|
||||||
Assert.That(TrackingPipelineBehavior<ModuleBehaviorRequest, string>.InvocationCount, Is.EqualTo(1));
|
|
||||||
});
|
|
||||||
|
|
||||||
await architecture.DestroyAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用于测试模块行为的最小架构实现。
|
/// 用于测试模块行为的最小架构实现。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -206,12 +206,6 @@ public class TestArchitectureWithRegistry : IArchitecture
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use RegisterCqrsPipelineBehavior<TBehavior>() instead.")]
|
|
||||||
public void RegisterMediatorBehavior<TBehavior>() where TBehavior : class
|
|
||||||
{
|
|
||||||
RegisterCqrsPipelineBehavior<TBehavior>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IArchitectureModule InstallModule(IArchitectureModule module)
|
public IArchitectureModule InstallModule(IArchitectureModule module)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@ -357,12 +351,6 @@ public class TestArchitectureWithoutRegistry : IArchitecture
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use RegisterCqrsPipelineBehavior<TBehavior>() instead.")]
|
|
||||||
public void RegisterMediatorBehavior<TBehavior>() where TBehavior : class
|
|
||||||
{
|
|
||||||
RegisterCqrsPipelineBehavior<TBehavior>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IArchitectureModule InstallModule(IArchitectureModule module)
|
public IArchitectureModule InstallModule(IArchitectureModule module)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|||||||
@ -1,99 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using System.Reflection;
|
|
||||||
using GFramework.Core.Abstractions.Architectures;
|
|
||||||
using GFramework.Core.Abstractions.Ioc;
|
|
||||||
using GFramework.Core.Architectures;
|
|
||||||
using GFramework.Core.Coroutine.Extensions;
|
|
||||||
using GFramework.Core.Ioc;
|
|
||||||
|
|
||||||
namespace GFramework.Core.Tests.Cqrs;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 锁定历史 Mediator 兼容入口的正式弃用策略。
|
|
||||||
/// 这些测试确保旧 API 不仅保留行为兼容,还会通过编译期提示和 IntelliSense 隐藏引导调用方迁移到新的 CQRS 命名。
|
|
||||||
/// </summary>
|
|
||||||
[TestFixture]
|
|
||||||
public class MediatorCompatibilityDeprecationTests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 验证公开兼容方法仍可用,但已被显式标记为未来移除的旧别名。
|
|
||||||
/// </summary>
|
|
||||||
[Test]
|
|
||||||
public void Legacy_Public_Methods_Should_Be_Obsolete_And_Hidden_From_Editor_Browsing()
|
|
||||||
{
|
|
||||||
AssertLegacyMethod(typeof(IArchitecture), nameof(IArchitecture.RegisterMediatorBehavior));
|
|
||||||
AssertLegacyMethod(typeof(IIocContainer), nameof(IIocContainer.RegisterMediatorBehavior));
|
|
||||||
AssertLegacyMethod(typeof(Architecture), nameof(Architecture.RegisterMediatorBehavior));
|
|
||||||
AssertLegacyMethod(typeof(MicrosoftDiContainer), nameof(MicrosoftDiContainer.RegisterMediatorBehavior));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 验证历史扩展类型会把迁移目标写入弃用说明,并从 IntelliSense 主路径隐藏。
|
|
||||||
/// </summary>
|
|
||||||
[Test]
|
|
||||||
public void Legacy_Extension_Types_Should_Be_Obsolete_And_Hidden_From_Editor_Browsing()
|
|
||||||
{
|
|
||||||
AssertLegacyType(
|
|
||||||
typeof(ContextAwareMediatorExtensions),
|
|
||||||
"Use GFramework.Core.Extensions.ContextAwareCqrsExtensions instead.");
|
|
||||||
AssertLegacyType(
|
|
||||||
typeof(ContextAwareMediatorCommandExtensions),
|
|
||||||
"Use GFramework.Cqrs.Extensions.ContextAwareCqrsCommandExtensions instead.");
|
|
||||||
AssertLegacyType(
|
|
||||||
typeof(ContextAwareMediatorQueryExtensions),
|
|
||||||
"Use GFramework.Cqrs.Extensions.ContextAwareCqrsQueryExtensions instead.");
|
|
||||||
AssertLegacyType(
|
|
||||||
typeof(MediatorCoroutineExtensions),
|
|
||||||
"Use GFramework.Core.Coroutine.Extensions.CqrsCoroutineExtensions instead.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 断言方法级兼容 API 具备统一的弃用元数据。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="declaringType">声明该方法的类型。</param>
|
|
||||||
/// <param name="methodName">方法名称。</param>
|
|
||||||
private static void AssertLegacyMethod(Type declaringType, string methodName)
|
|
||||||
{
|
|
||||||
var method = declaringType
|
|
||||||
.GetMethods(BindingFlags.Public | BindingFlags.Instance)
|
|
||||||
.Single(candidate => candidate.Name == methodName);
|
|
||||||
|
|
||||||
var obsoleteAttribute = method.GetCustomAttribute<ObsoleteAttribute>();
|
|
||||||
var editorBrowsableAttribute = method.GetCustomAttribute<EditorBrowsableAttribute>();
|
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
|
||||||
{
|
|
||||||
Assert.That(obsoleteAttribute, Is.Not.Null);
|
|
||||||
Assert.That(
|
|
||||||
obsoleteAttribute!.Message,
|
|
||||||
Does.Contain("Use RegisterCqrsPipelineBehavior<TBehavior>() instead."));
|
|
||||||
Assert.That(
|
|
||||||
obsoleteAttribute.Message,
|
|
||||||
Does.Contain("removed in a future major version"));
|
|
||||||
Assert.That(editorBrowsableAttribute, Is.Not.Null);
|
|
||||||
Assert.That(editorBrowsableAttribute!.State, Is.EqualTo(EditorBrowsableState.Never));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 断言类型级兼容扩展具备统一的弃用元数据。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">兼容扩展类型。</param>
|
|
||||||
/// <param name="expectedReplacementHint">期望的迁移提示。</param>
|
|
||||||
private static void AssertLegacyType(Type type, string expectedReplacementHint)
|
|
||||||
{
|
|
||||||
var obsoleteAttribute = type.GetCustomAttribute<ObsoleteAttribute>();
|
|
||||||
var editorBrowsableAttribute = type.GetCustomAttribute<EditorBrowsableAttribute>();
|
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
|
||||||
{
|
|
||||||
Assert.That(obsoleteAttribute, Is.Not.Null);
|
|
||||||
Assert.That(obsoleteAttribute!.Message, Does.Contain(expectedReplacementHint));
|
|
||||||
Assert.That(
|
|
||||||
obsoleteAttribute.Message,
|
|
||||||
Does.Contain("removed in a future major version"));
|
|
||||||
Assert.That(editorBrowsableAttribute, Is.Not.Null);
|
|
||||||
Assert.That(editorBrowsableAttribute!.State, Is.EqualTo(EditorBrowsableState.Never));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -21,9 +21,11 @@
|
|||||||
<ProjectReference Include="..\GFramework.Tests.Common\GFramework.Tests.Common.csproj"/>
|
<ProjectReference Include="..\GFramework.Tests.Common\GFramework.Tests.Common.csproj"/>
|
||||||
<ProjectReference Include="..\GFramework.Core.Abstractions\GFramework.Core.Abstractions.csproj"/>
|
<ProjectReference Include="..\GFramework.Core.Abstractions\GFramework.Core.Abstractions.csproj"/>
|
||||||
<ProjectReference Include="..\GFramework.Core\GFramework.Core.csproj"/>
|
<ProjectReference Include="..\GFramework.Core\GFramework.Core.csproj"/>
|
||||||
<ProjectReference Include="..\GFramework.SourceGenerators.Abstractions\GFramework.SourceGenerators.Abstractions.csproj"/>
|
<ProjectReference Include="..\GFramework.Core.SourceGenerators.Abstractions\GFramework.Core.SourceGenerators.Abstractions.csproj"/>
|
||||||
<ProjectReference Include="..\GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj"/>
|
<ProjectReference Include="..\GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj"
|
||||||
<ProjectReference Include="..\GFramework.SourceGenerators\GFramework.SourceGenerators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
|
OutputItemType="Analyzer"
|
||||||
|
ReferenceOutputAssembly="false"/>
|
||||||
|
<ProjectReference Include="..\GFramework.Core.SourceGenerators\GFramework.Core.SourceGenerators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using GFramework.Core.Abstractions.Architectures;
|
using GFramework.Core.Abstractions.Architectures;
|
||||||
using GFramework.Core.Abstractions.Enums;
|
using GFramework.Core.Abstractions.Enums;
|
||||||
@ -8,7 +7,6 @@ using GFramework.Core.Abstractions.Model;
|
|||||||
using GFramework.Core.Abstractions.Systems;
|
using GFramework.Core.Abstractions.Systems;
|
||||||
using GFramework.Core.Abstractions.Utility;
|
using GFramework.Core.Abstractions.Utility;
|
||||||
using GFramework.Core.Environment;
|
using GFramework.Core.Environment;
|
||||||
using GFramework.Core.Logging;
|
|
||||||
|
|
||||||
namespace GFramework.Core.Architectures;
|
namespace GFramework.Core.Architectures;
|
||||||
|
|
||||||
@ -156,20 +154,6 @@ public abstract class Architecture : IArchitecture
|
|||||||
_modules.RegisterCqrsPipelineBehavior<TBehavior>();
|
_modules.RegisterCqrsPipelineBehavior<TBehavior>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 注册 CQRS 请求管道行为。
|
|
||||||
/// 该成员保留旧名称以兼容历史调用点,内部行为与 <see cref="RegisterCqrsPipelineBehavior{TBehavior}" /> 一致。
|
|
||||||
/// 新代码不应继续依赖该别名;兼容层计划在未来的 major 版本中移除。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TBehavior">行为类型,必须是引用类型</typeparam>
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
[Obsolete(
|
|
||||||
"Use RegisterCqrsPipelineBehavior<TBehavior>() instead. This compatibility alias will be removed in a future major version.")]
|
|
||||||
public void RegisterMediatorBehavior<TBehavior>() where TBehavior : class
|
|
||||||
{
|
|
||||||
RegisterCqrsPipelineBehavior<TBehavior>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 从指定程序集显式注册 CQRS 处理器。
|
/// 从指定程序集显式注册 CQRS 处理器。
|
||||||
/// 该入口适用于把拆分到其他模块或扩展包程序集中的 handlers 接入当前架构。
|
/// 该入口适用于把拆分到其他模块或扩展包程序集中的 handlers 接入当前架构。
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using GFramework.Core.Abstractions.Architectures;
|
using GFramework.Core.Abstractions.Architectures;
|
||||||
using GFramework.Core.Abstractions.Logging;
|
using GFramework.Core.Abstractions.Logging;
|
||||||
@ -25,20 +24,6 @@ internal sealed class ArchitectureModules(
|
|||||||
services.Container.RegisterCqrsPipelineBehavior<TBehavior>();
|
services.Container.RegisterCqrsPipelineBehavior<TBehavior>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 注册 CQRS 请求管道行为。
|
|
||||||
/// 该成员保留旧名称以兼容历史调用点,内部行为与 <see cref="RegisterCqrsPipelineBehavior{TBehavior}" /> 一致。
|
|
||||||
/// 新代码不应继续依赖该别名;兼容层计划在未来的 major 版本中移除。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TBehavior">行为类型,必须是引用类型</typeparam>
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
[Obsolete(
|
|
||||||
"Use RegisterCqrsPipelineBehavior<TBehavior>() instead. This compatibility alias will be removed in a future major version.")]
|
|
||||||
public void RegisterMediatorBehavior<TBehavior>() where TBehavior : class
|
|
||||||
{
|
|
||||||
RegisterCqrsPipelineBehavior<TBehavior>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 从指定程序集显式注册 CQRS 处理器。
|
/// 从指定程序集显式注册 CQRS 处理器。
|
||||||
/// 该入口用于把默认架构程序集之外的扩展处理器接入当前架构容器。
|
/// 该入口用于把默认架构程序集之外的扩展处理器接入当前架构容器。
|
||||||
|
|||||||
@ -1,47 +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.
|
|
||||||
|
|
||||||
using System.ComponentModel;
|
|
||||||
using GFramework.Core.Abstractions.Coroutine;
|
|
||||||
using GFramework.Core.Abstractions.Rule;
|
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
|
||||||
|
|
||||||
namespace GFramework.Core.Coroutine.Extensions;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 提供 CQRS 命令与协程集成的扩展方法。
|
|
||||||
/// 该类型保留旧名称以兼容历史调用点;新代码应改用 <see cref="CqrsCoroutineExtensions" />。
|
|
||||||
/// 兼容层计划在未来的 major 版本中移除,因此不会继续承载新能力。
|
|
||||||
/// </summary>
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
[Obsolete(
|
|
||||||
"Use GFramework.Core.Coroutine.Extensions.CqrsCoroutineExtensions instead. This compatibility alias will be removed in a future major version.")]
|
|
||||||
public static class MediatorCoroutineExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 以协程方式发送无返回值 CQRS 命令并处理可能的异常。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TCommand">命令的类型。</typeparam>
|
|
||||||
/// <param name="contextAware">上下文感知对象,用于获取服务</param>
|
|
||||||
/// <param name="command">要发送的命令对象</param>
|
|
||||||
/// <param name="onError">发生异常时的回调处理函数</param>
|
|
||||||
/// <returns>协程枚举器,用于协程执行</returns>
|
|
||||||
public static IEnumerator<IYieldInstruction> SendCommandCoroutine<TCommand>(
|
|
||||||
this IContextAware contextAware,
|
|
||||||
TCommand command,
|
|
||||||
Action<Exception>? onError = null)
|
|
||||||
where TCommand : IRequest<Unit>
|
|
||||||
{
|
|
||||||
return CqrsCoroutineExtensions.SendCommandCoroutine(contextAware, command, onError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using GFramework.Core.Abstractions.Rule;
|
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs.Command;
|
|
||||||
using GFramework.Cqrs.Extensions;
|
|
||||||
|
|
||||||
namespace GFramework.Core.Extensions;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 提供对 <see cref="IContextAware" /> 接口的 CQRS 命令扩展方法。
|
|
||||||
/// 该类型保留旧名称以兼容历史调用点;新代码应改用 <see cref="ContextAwareCqrsCommandExtensions" />。
|
|
||||||
/// 兼容层计划在未来的 major 版本中移除,因此不会继续承载新能力。
|
|
||||||
/// </summary>
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
[Obsolete(
|
|
||||||
"Use GFramework.Cqrs.Extensions.ContextAwareCqrsCommandExtensions instead. This compatibility alias will be removed in a future major version.")]
|
|
||||||
public static class ContextAwareMediatorCommandExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 发送命令的同步版本(不推荐,仅用于兼容性)
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResponse">命令响应类型</typeparam>
|
|
||||||
/// <param name="contextAware">实现 IContextAware 接口的对象</param>
|
|
||||||
/// <param name="command">要发送的命令对象</param>
|
|
||||||
/// <returns>命令执行结果</returns>
|
|
||||||
/// <exception cref="ArgumentNullException">当 contextAware 或 command 为 null 时抛出</exception>
|
|
||||||
public static TResponse SendCommand<TResponse>(this IContextAware contextAware,
|
|
||||||
ICommand<TResponse> command)
|
|
||||||
{
|
|
||||||
return ContextAwareCqrsCommandExtensions.SendCommand(contextAware, command);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步发送命令并返回结果
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResponse">命令响应类型</typeparam>
|
|
||||||
/// <param name="contextAware">实现 IContextAware 接口的对象</param>
|
|
||||||
/// <param name="command">要发送的命令对象</param>
|
|
||||||
/// <param name="cancellationToken">取消令牌,用于取消操作</param>
|
|
||||||
/// <returns>包含命令执行结果的ValueTask</returns>
|
|
||||||
/// <exception cref="ArgumentNullException">当 contextAware 或 command 为 null 时抛出</exception>
|
|
||||||
public static ValueTask<TResponse> SendCommandAsync<TResponse>(this IContextAware contextAware,
|
|
||||||
ICommand<TResponse> command, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return ContextAwareCqrsCommandExtensions.SendCommandAsync(
|
|
||||||
contextAware,
|
|
||||||
command,
|
|
||||||
cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,123 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using GFramework.Core.Abstractions.Rule;
|
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
|
||||||
using GFramework.Cqrs.Extensions;
|
|
||||||
|
|
||||||
namespace GFramework.Core.Extensions;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 提供对 <see cref="IContextAware" /> 接口的 CQRS 统一接口扩展方法。
|
|
||||||
/// 该类型保留旧名称以兼容历史调用点;新代码应改用 <see cref="ContextAwareCqrsExtensions" />。
|
|
||||||
/// 兼容层计划在未来的 major 版本中移除,因此不会继续承载新能力。
|
|
||||||
/// </summary>
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
[Obsolete(
|
|
||||||
"Use GFramework.Core.Extensions.ContextAwareCqrsExtensions instead. This compatibility alias will be removed in a future major version.")]
|
|
||||||
public static class ContextAwareMediatorExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 发送请求(统一处理 Command/Query)
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResponse">响应类型</typeparam>
|
|
||||||
/// <param name="contextAware">实现 IContextAware 接口的对象</param>
|
|
||||||
/// <param name="request">要发送的请求</param>
|
|
||||||
/// <param name="cancellationToken">取消令牌</param>
|
|
||||||
/// <returns>请求结果</returns>
|
|
||||||
/// <exception cref="ArgumentNullException">当 contextAware 或 request 为 null 时抛出</exception>
|
|
||||||
public static ValueTask<TResponse> SendRequestAsync<TResponse>(this IContextAware contextAware,
|
|
||||||
IRequest<TResponse> request, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return ContextAwareCqrsExtensions.SendRequestAsync(
|
|
||||||
contextAware,
|
|
||||||
request,
|
|
||||||
cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 发送请求(同步版本,不推荐)
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResponse">响应类型</typeparam>
|
|
||||||
/// <param name="contextAware">实现 IContextAware 接口的对象</param>
|
|
||||||
/// <param name="request">要发送的请求</param>
|
|
||||||
/// <returns>请求结果</returns>
|
|
||||||
/// <exception cref="ArgumentNullException">当 contextAware 或 request 为 null 时抛出</exception>
|
|
||||||
public static TResponse SendRequest<TResponse>(this IContextAware contextAware,
|
|
||||||
IRequest<TResponse> request)
|
|
||||||
{
|
|
||||||
return ContextAwareCqrsExtensions.SendRequest(contextAware, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 发布通知(一对多事件)
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TNotification">通知类型</typeparam>
|
|
||||||
/// <param name="contextAware">实现 IContextAware 接口的对象</param>
|
|
||||||
/// <param name="notification">要发布的通知</param>
|
|
||||||
/// <param name="cancellationToken">取消令牌</param>
|
|
||||||
/// <returns>异步任务</returns>
|
|
||||||
/// <exception cref="ArgumentNullException">当 contextAware 或 notification 为 null 时抛出</exception>
|
|
||||||
public static ValueTask PublishAsync<TNotification>(this IContextAware contextAware,
|
|
||||||
TNotification notification, CancellationToken cancellationToken = default)
|
|
||||||
where TNotification : INotification
|
|
||||||
{
|
|
||||||
return ContextAwareCqrsExtensions.PublishAsync(
|
|
||||||
contextAware,
|
|
||||||
notification,
|
|
||||||
cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建流式请求(用于大数据集)
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResponse">响应类型</typeparam>
|
|
||||||
/// <param name="contextAware">实现 IContextAware 接口的对象</param>
|
|
||||||
/// <param name="request">流式请求</param>
|
|
||||||
/// <param name="cancellationToken">取消令牌</param>
|
|
||||||
/// <returns>异步响应流</returns>
|
|
||||||
/// <exception cref="ArgumentNullException">当 contextAware 或 request 为 null 时抛出</exception>
|
|
||||||
public static IAsyncEnumerable<TResponse> CreateStream<TResponse>(this IContextAware contextAware,
|
|
||||||
IStreamRequest<TResponse> request, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return ContextAwareCqrsExtensions.CreateStream(
|
|
||||||
contextAware,
|
|
||||||
request,
|
|
||||||
cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 发送命令(无返回值)
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TCommand">命令类型</typeparam>
|
|
||||||
/// <param name="contextAware">实现 IContextAware 接口的对象</param>
|
|
||||||
/// <param name="command">要发送的命令</param>
|
|
||||||
/// <param name="cancellationToken">取消令牌</param>
|
|
||||||
/// <returns>异步任务</returns>
|
|
||||||
/// <exception cref="ArgumentNullException">当 contextAware 或 command 为 null 时抛出</exception>
|
|
||||||
public static ValueTask SendAsync<TCommand>(this IContextAware contextAware, TCommand command,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
where TCommand : IRequest<Unit>
|
|
||||||
{
|
|
||||||
return ContextAwareCqrsExtensions.SendAsync(
|
|
||||||
contextAware,
|
|
||||||
command,
|
|
||||||
cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 发送命令(有返回值)
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResponse">响应类型</typeparam>
|
|
||||||
/// <param name="contextAware">实现 IContextAware 接口的对象</param>
|
|
||||||
/// <param name="command">要发送的命令</param>
|
|
||||||
/// <param name="cancellationToken">取消令牌</param>
|
|
||||||
/// <returns>命令执行结果</returns>
|
|
||||||
/// <exception cref="ArgumentNullException">当 contextAware 或 command 为 null 时抛出</exception>
|
|
||||||
public static ValueTask<TResponse> SendAsync<TResponse>(this IContextAware contextAware,
|
|
||||||
IRequest<TResponse> command, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return ContextAwareCqrsExtensions.SendAsync(
|
|
||||||
contextAware,
|
|
||||||
command,
|
|
||||||
cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using GFramework.Core.Abstractions.Rule;
|
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs.Query;
|
|
||||||
using GFramework.Cqrs.Extensions;
|
|
||||||
|
|
||||||
namespace GFramework.Core.Extensions;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 提供对 <see cref="IContextAware" /> 接口的 CQRS 查询扩展方法。
|
|
||||||
/// 该类型保留旧名称以兼容历史调用点;新代码应改用 <see cref="ContextAwareCqrsQueryExtensions" />。
|
|
||||||
/// 兼容层计划在未来的 major 版本中移除,因此不会继续承载新能力。
|
|
||||||
/// </summary>
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
[Obsolete(
|
|
||||||
"Use GFramework.Cqrs.Extensions.ContextAwareCqrsQueryExtensions instead. This compatibility alias will be removed in a future major version.")]
|
|
||||||
public static class ContextAwareMediatorQueryExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 发送查询的同步版本(不推荐,仅用于兼容性)
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResponse">查询响应类型</typeparam>
|
|
||||||
/// <param name="contextAware">实现 IContextAware 接口的对象</param>
|
|
||||||
/// <param name="query">要发送的查询对象</param>
|
|
||||||
/// <returns>查询结果</returns>
|
|
||||||
/// <exception cref="ArgumentNullException">当 contextAware 或 query 为 null 时抛出</exception>
|
|
||||||
public static TResponse SendQuery<TResponse>(this IContextAware contextAware, IQuery<TResponse> query)
|
|
||||||
{
|
|
||||||
return ContextAwareCqrsQueryExtensions.SendQuery(contextAware, query);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步发送查询并返回结果
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResponse">查询响应类型</typeparam>
|
|
||||||
/// <param name="contextAware">实现 IContextAware 接口的对象</param>
|
|
||||||
/// <param name="query">要发送的查询对象</param>
|
|
||||||
/// <param name="cancellationToken">取消令牌,用于取消操作</param>
|
|
||||||
/// <returns>包含查询结果的ValueTask</returns>
|
|
||||||
/// <exception cref="ArgumentNullException">当 contextAware 或 query 为 null 时抛出</exception>
|
|
||||||
public static ValueTask<TResponse> SendQueryAsync<TResponse>(this IContextAware contextAware,
|
|
||||||
IQuery<TResponse> query, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return ContextAwareCqrsQueryExtensions.SendQueryAsync(
|
|
||||||
contextAware,
|
|
||||||
query,
|
|
||||||
cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,4 +1,3 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using GFramework.Core.Abstractions.Bases;
|
using GFramework.Core.Abstractions.Bases;
|
||||||
using GFramework.Core.Abstractions.Ioc;
|
using GFramework.Core.Abstractions.Ioc;
|
||||||
@ -367,20 +366,6 @@ public class MicrosoftDiContainer(IServiceCollection? serviceCollection = null)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 注册 CQRS 请求管道行为。
|
|
||||||
/// 该成员保留旧名称以兼容历史调用点,内部行为与 <see cref="RegisterCqrsPipelineBehavior{TBehavior}" /> 一致。
|
|
||||||
/// 新代码不应继续依赖该别名;兼容层计划在未来的 major 版本中移除。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TBehavior">行为类型,必须是引用类型</typeparam>
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
[Obsolete(
|
|
||||||
"Use RegisterCqrsPipelineBehavior<TBehavior>() instead. This compatibility alias will be removed in a future major version.")]
|
|
||||||
public void RegisterMediatorBehavior<TBehavior>() where TBehavior : class
|
|
||||||
{
|
|
||||||
RegisterCqrsPipelineBehavior<TBehavior>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 从指定程序集显式注册 CQRS 处理器。
|
/// 从指定程序集显式注册 CQRS 处理器。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -337,10 +337,17 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type is INamedTypeSymbol namedType &&
|
if (type is INamedTypeSymbol namedType)
|
||||||
SymbolEqualityComparer.Default.Equals(namedType.ContainingAssembly, compilation.Assembly))
|
|
||||||
{
|
{
|
||||||
runtimeTypeReference = RuntimeTypeReferenceSpec.FromReflectionLookup(
|
if (SymbolEqualityComparer.Default.Equals(namedType.ContainingAssembly, compilation.Assembly))
|
||||||
|
{
|
||||||
|
runtimeTypeReference = RuntimeTypeReferenceSpec.FromReflectionLookup(
|
||||||
|
GetReflectionTypeMetadataName(namedType));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
runtimeTypeReference = RuntimeTypeReferenceSpec.FromExternalReflectionLookup(
|
||||||
|
namedType.ContainingAssembly.Identity.Name,
|
||||||
GetReflectionTypeMetadataName(namedType));
|
GetReflectionTypeMetadataName(namedType));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -388,8 +395,10 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
genericTypeDefinitionReference = null;
|
genericTypeDefinitionReference = RuntimeTypeReferenceSpec.FromExternalReflectionLookup(
|
||||||
return false;
|
genericTypeDefinition.ContainingAssembly.Identity.Name,
|
||||||
|
GetReflectionTypeMetadataName(genericTypeDefinition));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool CanReferenceFromGeneratedRegistry(Compilation compilation, ITypeSymbol type)
|
private static bool CanReferenceFromGeneratedRegistry(Compilation compilation, ITypeSymbol type)
|
||||||
@ -492,6 +501,9 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
|||||||
!registration.PreciseReflectedRegistrations.IsDefaultOrEmpty);
|
!registration.PreciseReflectedRegistrations.IsDefaultOrEmpty);
|
||||||
var hasRuntimeInterfaceDiscovery = registrations.Any(static registration =>
|
var hasRuntimeInterfaceDiscovery = registrations.Any(static registration =>
|
||||||
registration.RequiresRuntimeInterfaceDiscovery);
|
registration.RequiresRuntimeInterfaceDiscovery);
|
||||||
|
var hasExternalAssemblyTypeLookups = registrations.Any(static registration =>
|
||||||
|
registration.PreciseReflectedRegistrations.Any(static preciseRegistration =>
|
||||||
|
preciseRegistration.ServiceTypeArguments.Any(ContainsExternalAssemblyTypeLookup)));
|
||||||
var builder = new StringBuilder();
|
var builder = new StringBuilder();
|
||||||
builder.AppendLine("// <auto-generated />");
|
builder.AppendLine("// <auto-generated />");
|
||||||
builder.AppendLine("#nullable enable");
|
builder.AppendLine("#nullable enable");
|
||||||
@ -556,10 +568,13 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
|||||||
|
|
||||||
builder.AppendLine(" }");
|
builder.AppendLine(" }");
|
||||||
|
|
||||||
if (hasRuntimeInterfaceDiscovery)
|
if (hasRuntimeInterfaceDiscovery || hasExternalAssemblyTypeLookups)
|
||||||
{
|
{
|
||||||
builder.AppendLine();
|
builder.AppendLine();
|
||||||
AppendReflectionHelpers(builder);
|
AppendReflectionHelpers(
|
||||||
|
builder,
|
||||||
|
hasRuntimeInterfaceDiscovery,
|
||||||
|
hasExternalAssemblyTypeLookups);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.AppendLine("}");
|
builder.AppendLine("}");
|
||||||
@ -910,14 +925,68 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
|||||||
builder.Append(indent);
|
builder.Append(indent);
|
||||||
builder.Append("var ");
|
builder.Append("var ");
|
||||||
builder.Append(variableBaseName);
|
builder.Append(variableBaseName);
|
||||||
builder.Append(" = registryAssembly.GetType(\"");
|
if (string.IsNullOrWhiteSpace(runtimeTypeReference.ReflectionAssemblyName))
|
||||||
builder.Append(EscapeStringLiteral(reflectionTypeMetadataName));
|
{
|
||||||
builder.AppendLine("\", throwOnError: false, ignoreCase: false);");
|
builder.Append(" = registryAssembly.GetType(\"");
|
||||||
|
builder.Append(EscapeStringLiteral(reflectionTypeMetadataName));
|
||||||
|
builder.AppendLine("\", throwOnError: false, ignoreCase: false);");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.Append(" = ResolveReferencedAssemblyType(\"");
|
||||||
|
builder.Append(EscapeStringLiteral(runtimeTypeReference.ReflectionAssemblyName!));
|
||||||
|
builder.Append("\", \"");
|
||||||
|
builder.Append(EscapeStringLiteral(reflectionTypeMetadataName));
|
||||||
|
builder.AppendLine("\");");
|
||||||
|
}
|
||||||
|
|
||||||
return variableBaseName;
|
return variableBaseName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AppendReflectionHelpers(StringBuilder builder)
|
private static void AppendReflectionHelpers(
|
||||||
|
StringBuilder builder,
|
||||||
|
bool includeRuntimeInterfaceDiscoveryHelpers,
|
||||||
|
bool includeExternalAssemblyTypeLookupHelpers)
|
||||||
{
|
{
|
||||||
|
if (includeExternalAssemblyTypeLookupHelpers)
|
||||||
|
{
|
||||||
|
builder.AppendLine(
|
||||||
|
" private static global::System.Type? ResolveReferencedAssemblyType(string assemblyName, string typeMetadataName)");
|
||||||
|
builder.AppendLine(" {");
|
||||||
|
builder.AppendLine(" var assembly = ResolveReferencedAssembly(assemblyName);");
|
||||||
|
builder.AppendLine(
|
||||||
|
" return assembly?.GetType(typeMetadataName, throwOnError: false, ignoreCase: false);");
|
||||||
|
builder.AppendLine(" }");
|
||||||
|
builder.AppendLine();
|
||||||
|
builder.AppendLine(
|
||||||
|
" private static global::System.Reflection.Assembly? ResolveReferencedAssembly(string assemblyName)");
|
||||||
|
builder.AppendLine(" {");
|
||||||
|
builder.AppendLine(
|
||||||
|
" foreach (var assembly in global::System.AppDomain.CurrentDomain.GetAssemblies())");
|
||||||
|
builder.AppendLine(" {");
|
||||||
|
builder.AppendLine(
|
||||||
|
" if (global::System.StringComparer.Ordinal.Equals(assembly.GetName().Name, assemblyName))");
|
||||||
|
builder.AppendLine(" return assembly;");
|
||||||
|
builder.AppendLine(" }");
|
||||||
|
builder.AppendLine();
|
||||||
|
builder.AppendLine(" try");
|
||||||
|
builder.AppendLine(" {");
|
||||||
|
builder.AppendLine(
|
||||||
|
" return global::System.Reflection.Assembly.Load(new global::System.Reflection.AssemblyName(assemblyName));");
|
||||||
|
builder.AppendLine(" }");
|
||||||
|
builder.AppendLine(" catch");
|
||||||
|
builder.AppendLine(" {");
|
||||||
|
builder.AppendLine(" return null;");
|
||||||
|
builder.AppendLine(" }");
|
||||||
|
builder.AppendLine(" }");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!includeRuntimeInterfaceDiscoveryHelpers)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (includeExternalAssemblyTypeLookupHelpers)
|
||||||
|
builder.AppendLine();
|
||||||
|
|
||||||
// Emit the runtime helper methods only when at least one handler still needs implementation-scoped
|
// Emit the runtime helper methods only when at least one handler still needs implementation-scoped
|
||||||
// interface discovery after all direct / precise registrations have been emitted.
|
// interface discovery after all direct / precise registrations have been emitted.
|
||||||
builder.AppendLine(
|
builder.AppendLine(
|
||||||
@ -1038,6 +1107,32 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
|||||||
.Replace("\r", "\\r");
|
.Replace("\r", "\\r");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool ContainsExternalAssemblyTypeLookup(RuntimeTypeReferenceSpec runtimeTypeReference)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(runtimeTypeReference.ReflectionAssemblyName))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (runtimeTypeReference.ArrayElementTypeReference is not null &&
|
||||||
|
ContainsExternalAssemblyTypeLookup(runtimeTypeReference.ArrayElementTypeReference))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runtimeTypeReference.GenericTypeDefinitionReference is not null &&
|
||||||
|
ContainsExternalAssemblyTypeLookup(runtimeTypeReference.GenericTypeDefinitionReference))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var genericTypeArgument in runtimeTypeReference.GenericTypeArguments)
|
||||||
|
{
|
||||||
|
if (ContainsExternalAssemblyTypeLookup(genericTypeArgument))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly record struct HandlerRegistrationSpec(
|
private readonly record struct HandlerRegistrationSpec(
|
||||||
string HandlerInterfaceDisplayName,
|
string HandlerInterfaceDisplayName,
|
||||||
string ImplementationTypeDisplayName,
|
string ImplementationTypeDisplayName,
|
||||||
@ -1058,6 +1153,7 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
|||||||
private sealed record RuntimeTypeReferenceSpec(
|
private sealed record RuntimeTypeReferenceSpec(
|
||||||
string? TypeDisplayName,
|
string? TypeDisplayName,
|
||||||
string? ReflectionTypeMetadataName,
|
string? ReflectionTypeMetadataName,
|
||||||
|
string? ReflectionAssemblyName,
|
||||||
RuntimeTypeReferenceSpec? ArrayElementTypeReference,
|
RuntimeTypeReferenceSpec? ArrayElementTypeReference,
|
||||||
int ArrayRank,
|
int ArrayRank,
|
||||||
RuntimeTypeReferenceSpec? GenericTypeDefinitionReference,
|
RuntimeTypeReferenceSpec? GenericTypeDefinitionReference,
|
||||||
@ -1065,19 +1161,28 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
|||||||
{
|
{
|
||||||
public static RuntimeTypeReferenceSpec FromDirectReference(string typeDisplayName)
|
public static RuntimeTypeReferenceSpec FromDirectReference(string typeDisplayName)
|
||||||
{
|
{
|
||||||
return new RuntimeTypeReferenceSpec(typeDisplayName, null, null, 0, null,
|
return new RuntimeTypeReferenceSpec(typeDisplayName, null, null, null, 0, null,
|
||||||
ImmutableArray<RuntimeTypeReferenceSpec>.Empty);
|
ImmutableArray<RuntimeTypeReferenceSpec>.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RuntimeTypeReferenceSpec FromReflectionLookup(string reflectionTypeMetadataName)
|
public static RuntimeTypeReferenceSpec FromReflectionLookup(string reflectionTypeMetadataName)
|
||||||
{
|
{
|
||||||
return new RuntimeTypeReferenceSpec(null, reflectionTypeMetadataName, null, 0, null,
|
return new RuntimeTypeReferenceSpec(null, reflectionTypeMetadataName, null, null, 0, null,
|
||||||
|
ImmutableArray<RuntimeTypeReferenceSpec>.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RuntimeTypeReferenceSpec FromExternalReflectionLookup(
|
||||||
|
string reflectionAssemblyName,
|
||||||
|
string reflectionTypeMetadataName)
|
||||||
|
{
|
||||||
|
return new RuntimeTypeReferenceSpec(null, reflectionTypeMetadataName, reflectionAssemblyName, null, 0,
|
||||||
|
null,
|
||||||
ImmutableArray<RuntimeTypeReferenceSpec>.Empty);
|
ImmutableArray<RuntimeTypeReferenceSpec>.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RuntimeTypeReferenceSpec FromArray(RuntimeTypeReferenceSpec elementTypeReference, int arrayRank)
|
public static RuntimeTypeReferenceSpec FromArray(RuntimeTypeReferenceSpec elementTypeReference, int arrayRank)
|
||||||
{
|
{
|
||||||
return new RuntimeTypeReferenceSpec(null, null, elementTypeReference, arrayRank, null,
|
return new RuntimeTypeReferenceSpec(null, null, null, elementTypeReference, arrayRank, null,
|
||||||
ImmutableArray<RuntimeTypeReferenceSpec>.Empty);
|
ImmutableArray<RuntimeTypeReferenceSpec>.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1085,7 +1190,7 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
|||||||
RuntimeTypeReferenceSpec genericTypeDefinitionReference,
|
RuntimeTypeReferenceSpec genericTypeDefinitionReference,
|
||||||
ImmutableArray<RuntimeTypeReferenceSpec> genericTypeArguments)
|
ImmutableArray<RuntimeTypeReferenceSpec> genericTypeArguments)
|
||||||
{
|
{
|
||||||
return new RuntimeTypeReferenceSpec(null, null, null, 0, genericTypeDefinitionReference,
|
return new RuntimeTypeReferenceSpec(null, null, null, null, 0, genericTypeDefinitionReference,
|
||||||
genericTypeArguments);
|
genericTypeArguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<PackageId>GeWuYou.$(AssemblyName)</PackageId>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
<IsRoslynAnalyzer>true</IsRoslynAnalyzer>
|
||||||
|
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||||
|
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
|
||||||
|
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" 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="System.Text.Json" Version="8.0.6" PrivateAssets="all"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj" PrivateAssets="all"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="..\GFramework.SourceGenerators.Common\Internals\IsExternalInit.cs"
|
||||||
|
Link="Internals\IsExternalInit.cs"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="$(OutputPath)\$(AssemblyName).dll"
|
||||||
|
Pack="true"
|
||||||
|
PackagePath="analyzers/dotnet/cs"
|
||||||
|
Visible="false"/>
|
||||||
|
<None Include="$(OutputPath)\GFramework.SourceGenerators.Common.dll"
|
||||||
|
Pack="true"
|
||||||
|
PackagePath="analyzers/dotnet/cs"
|
||||||
|
Visible="false"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="$(OutputPath)\GFramework.SourceGenerators.Common.dll" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
|
||||||
|
<None Include="$(OutputPath)\GFramework.SourceGenerators.Common.xml" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
13
GFramework.Cqrs.SourceGenerators/GlobalUsings.cs
Normal file
13
GFramework.Cqrs.SourceGenerators/GlobalUsings.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
global using System;
|
||||||
|
global using System.Collections.Generic;
|
||||||
|
global using System.Collections.Immutable;
|
||||||
|
global using System.IO;
|
||||||
|
global using System.Linq;
|
||||||
|
global using System.Text;
|
||||||
|
global using System.Text.Json;
|
||||||
|
global using System.Threading;
|
||||||
|
global using System.Threading.Tasks;
|
||||||
|
global using Microsoft.CodeAnalysis;
|
||||||
|
global using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
global using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
global using Microsoft.CodeAnalysis.Text;
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
; Shipped analyzer release
|
||||||
|
; Intentionally empty until the split game source-generator package ships a stable analyzer release.
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
; Unshipped analyzer release
|
||||||
|
; https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
|
||||||
|
|
||||||
|
### New Rules
|
||||||
|
|
||||||
|
Rule ID | Category | Severity | Notes
|
||||||
|
---------------------|------------------------------------|----------|-------------------------
|
||||||
|
GF_ConfigSchema_001 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
||||||
|
GF_ConfigSchema_002 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
||||||
|
GF_ConfigSchema_003 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
||||||
|
GF_ConfigSchema_004 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
||||||
|
GF_ConfigSchema_005 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
||||||
|
GF_ConfigSchema_006 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
||||||
|
GF_ConfigSchema_007 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
||||||
|
GF_ConfigSchema_008 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
||||||
|
GF_ConfigSchema_009 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
||||||
|
GF_ConfigSchema_010 | GFramework.SourceGenerators.Config | Error | ConfigSchemaDiagnostics
|
||||||
@ -31,7 +31,8 @@ public sealed class SchemaConfigGenerator : IIncrementalGenerator
|
|||||||
private const string LookupIndexReferencePropertyMessage =
|
private const string LookupIndexReferencePropertyMessage =
|
||||||
"Reference properties are excluded from generated lookup indexes because they already carry cross-table semantics.";
|
"Reference properties are excluded from generated lookup indexes because they already carry cross-table semantics.";
|
||||||
|
|
||||||
private const string SupportedStringFormatNames = "'date', 'date-time', 'duration', 'email', 'time', 'uri', and 'uuid'";
|
private const string SupportedStringFormatNames =
|
||||||
|
"'date', 'date-time', 'duration', 'email', 'time', 'uri', and 'uuid'";
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||||
@ -3183,7 +3184,8 @@ public sealed class SchemaConfigGenerator : IIncrementalGenerator
|
|||||||
|
|
||||||
var targets = dependency.Value
|
var targets = dependency.Value
|
||||||
.EnumerateArray()
|
.EnumerateArray()
|
||||||
.Where(static item => item.ValueKind == JsonValueKind.String && !string.IsNullOrWhiteSpace(item.GetString()))
|
.Where(static item =>
|
||||||
|
item.ValueKind == JsonValueKind.String && !string.IsNullOrWhiteSpace(item.GetString()))
|
||||||
.Select(static item => item.GetString()!)
|
.Select(static item => item.GetString()!)
|
||||||
.Distinct(StringComparer.Ordinal)
|
.Distinct(StringComparer.Ordinal)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<PackageId>GeWuYou.$(AssemblyName)</PackageId>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
<IsRoslynAnalyzer>true</IsRoslynAnalyzer>
|
||||||
|
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||||
|
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
|
||||||
|
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" 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="System.Text.Json" Version="8.0.6" PrivateAssets="all"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj" PrivateAssets="all"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="..\GFramework.SourceGenerators.Common\Internals\IsExternalInit.cs"
|
||||||
|
Link="Internals\IsExternalInit.cs"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<AdditionalFiles Include="AnalyzerReleases.Shipped.md"/>
|
||||||
|
<AdditionalFiles Include="AnalyzerReleases.Unshipped.md"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="$(OutputPath)\$(AssemblyName).dll"
|
||||||
|
Pack="true"
|
||||||
|
PackagePath="analyzers/dotnet/cs"
|
||||||
|
Visible="false"/>
|
||||||
|
<None Include="$(OutputPath)\GFramework.SourceGenerators.Common.dll"
|
||||||
|
Pack="true"
|
||||||
|
PackagePath="analyzers/dotnet/cs"
|
||||||
|
Visible="false"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="$(OutputPath)\GFramework.SourceGenerators.Common.dll" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
|
||||||
|
<None Include="$(OutputPath)\GFramework.SourceGenerators.Common.xml" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
|
||||||
|
<None Include="GeWuYou.GFramework.Game.SourceGenerators.targets" Pack="true" PackagePath="build" Visible="false"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@ -1,8 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<!-- This file is automatically generated by the NuGet package -->
|
|
||||||
<!-- It ensures that the source generators are properly registered during build -->
|
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<!--
|
<!--
|
||||||
消费项目默认从 schemas/ 目录收集配置 schema。
|
消费项目默认从 schemas/ 目录收集配置 schema。
|
||||||
@ -12,15 +9,8 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!--
|
<Analyzer Include="$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.Game.SourceGenerators.dll"
|
||||||
仅在 NuGet 打包布局存在时自动注入 analyzer。
|
Condition="Exists('$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.Game.SourceGenerators.dll')"/>
|
||||||
仓库内项目引用场景会通过 ProjectReference(OutputItemType=Analyzer) 提供生成器,
|
|
||||||
因此这里需要避免对不存在的打包路径做无效引用。
|
|
||||||
-->
|
|
||||||
<Analyzer Include="$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.SourceGenerators.dll"
|
|
||||||
Condition="Exists('$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.SourceGenerators.dll')"/>
|
|
||||||
<Analyzer Include="$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.SourceGenerators.Abstractions.dll"
|
|
||||||
Condition="Exists('$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.SourceGenerators.Abstractions.dll')"/>
|
|
||||||
<Analyzer Include="$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.SourceGenerators.Common.dll"
|
<Analyzer Include="$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.SourceGenerators.Common.dll"
|
||||||
Condition="Exists('$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.SourceGenerators.Common.dll')"/>
|
Condition="Exists('$(MSBuildThisFileDirectory)../analyzers/dotnet/cs/GFramework.SourceGenerators.Common.dll')"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -33,8 +23,7 @@
|
|||||||
<AdditionalFiles Include="$(MSBuildProjectDirectory)/$(GFrameworkConfigSchemaDirectory)/**/*.schema.json"/>
|
<AdditionalFiles Include="$(MSBuildProjectDirectory)/$(GFrameworkConfigSchemaDirectory)/**/*.schema.json"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- Ensure the analyzers are loaded -->
|
<Target Name="EnsureGFrameworkGameAnalyzers" BeforeTargets="CoreCompile">
|
||||||
<Target Name="EnsureGFrameworkAnalyzers" BeforeTargets="CoreCompile">
|
<Message Text="Loading GFramework.Game source generators" Importance="high"/>
|
||||||
<Message Text="Loading GFramework source generators" Importance="high"/>
|
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
14
GFramework.Game.SourceGenerators/GlobalUsings.cs
Normal file
14
GFramework.Game.SourceGenerators/GlobalUsings.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
global using System;
|
||||||
|
global using System.Collections.Generic;
|
||||||
|
global using System.Collections.Immutable;
|
||||||
|
global using System.Globalization;
|
||||||
|
global using System.IO;
|
||||||
|
global using System.Linq;
|
||||||
|
global using System.Text;
|
||||||
|
global using System.Text.Json;
|
||||||
|
global using System.Threading;
|
||||||
|
global using System.Threading.Tasks;
|
||||||
|
global using Microsoft.CodeAnalysis;
|
||||||
|
global using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
global using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
global using Microsoft.CodeAnalysis.Text;
|
||||||
@ -20,13 +20,14 @@
|
|||||||
<ProjectReference Include="..\GFramework.Game\GFramework.Game.csproj"/>
|
<ProjectReference Include="..\GFramework.Game\GFramework.Game.csproj"/>
|
||||||
<ProjectReference Include="..\GFramework.Core\GFramework.Core.csproj"/>
|
<ProjectReference Include="..\GFramework.Core\GFramework.Core.csproj"/>
|
||||||
<ProjectReference Include="..\GFramework.Godot\GFramework.Godot.csproj"/>
|
<ProjectReference Include="..\GFramework.Godot\GFramework.Godot.csproj"/>
|
||||||
<ProjectReference Include="..\GFramework.SourceGenerators.Abstractions\GFramework.SourceGenerators.Abstractions.csproj"
|
<ProjectReference Include="..\GFramework.Core.SourceGenerators.Abstractions\GFramework.Core.SourceGenerators.Abstractions.csproj"/>
|
||||||
OutputItemType="Analyzer"
|
|
||||||
ReferenceOutputAssembly="false"/>
|
|
||||||
<ProjectReference Include="..\GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj"
|
<ProjectReference Include="..\GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj"
|
||||||
OutputItemType="Analyzer"
|
OutputItemType="Analyzer"
|
||||||
ReferenceOutputAssembly="false"/>
|
ReferenceOutputAssembly="false"/>
|
||||||
<ProjectReference Include="..\GFramework.SourceGenerators\GFramework.SourceGenerators.csproj"
|
<ProjectReference Include="..\GFramework.Core.SourceGenerators\GFramework.Core.SourceGenerators.csproj"
|
||||||
|
OutputItemType="Analyzer"
|
||||||
|
ReferenceOutputAssembly="false"/>
|
||||||
|
<ProjectReference Include="..\GFramework.Game.SourceGenerators\GFramework.Game.SourceGenerators.csproj"
|
||||||
OutputItemType="Analyzer"
|
OutputItemType="Analyzer"
|
||||||
ReferenceOutputAssembly="false"/>
|
ReferenceOutputAssembly="false"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -35,6 +36,6 @@
|
|||||||
通过仓库内的 targets 复用消费者默认约定,确保测试项目与真实消费项目一样
|
通过仓库内的 targets 复用消费者默认约定,确保测试项目与真实消费项目一样
|
||||||
自动拾取 schemas/**/*.schema.json 作为 Source Generator 的 AdditionalFiles。
|
自动拾取 schemas/**/*.schema.json 作为 Source Generator 的 AdditionalFiles。
|
||||||
-->
|
-->
|
||||||
<Import Project="..\GFramework.SourceGenerators\GeWuYou.GFramework.SourceGenerators.targets"/>
|
<Import Project="..\GFramework.Game.SourceGenerators\GeWuYou.GFramework.Game.SourceGenerators.targets"/>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -827,10 +827,10 @@ public class CqrsHandlerRegistryGeneratorTests
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 验证当外部基类暴露的 handler interface 含有生成注册器顶层上下文不可直接引用的 protected 类型时,
|
/// 验证当外部基类暴露的 handler interface 含有生成注册器顶层上下文不可直接引用的 protected 类型时,
|
||||||
/// 生成器会保留已知直注册,并只对剩余未知接口做本地 interface discovery。
|
/// 生成器会输出定向程序集查找,而不是继续退回 implementation 级接口发现。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void Generates_Partial_Runtime_Interface_Discovery_For_Inaccessible_External_Protected_Types()
|
public void Generates_Precise_Assembly_Type_Lookups_For_Inaccessible_External_Protected_Types()
|
||||||
{
|
{
|
||||||
const string contractsSource = """
|
const string contractsSource = """
|
||||||
namespace GFramework.Cqrs.Abstractions.Cqrs
|
namespace GFramework.Cqrs.Abstractions.Cqrs
|
||||||
@ -931,30 +931,28 @@ public class CqrsHandlerRegistryGeneratorTests
|
|||||||
Assert.That(
|
Assert.That(
|
||||||
generatedSource,
|
generatedSource,
|
||||||
Does.Contain(
|
Does.Contain(
|
||||||
"var knownServiceTypes0 = new global::System.Collections.Generic.HashSet<global::System.Type>();"));
|
"ResolveReferencedAssemblyType(\"Dependency\", \"Dep.VisibilityScope+ProtectedRequest\")"));
|
||||||
Assert.That(
|
Assert.That(
|
||||||
generatedSource,
|
generatedSource,
|
||||||
Does.Contain(
|
Does.Contain(
|
||||||
"// Remaining runtime interface discovery target: GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<Dep.VisibilityScope.ProtectedRequest, Dep.VisibilityScope.ProtectedResponse[]>"));
|
"ResolveReferencedAssemblyType(\"Dependency\", \"Dep.VisibilityScope+ProtectedResponse\")"));
|
||||||
Assert.That(
|
Assert.That(
|
||||||
generatedSource,
|
generatedSource,
|
||||||
Does.Contain(
|
Does.Contain(
|
||||||
"knownServiceTypes0.Add(typeof(global::GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<global::Dep.VisibleRequest, string>));"));
|
"typeof(global::GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<global::Dep.VisibleRequest, string>)"));
|
||||||
Assert.That(
|
Assert.That(
|
||||||
generatedSource,
|
generatedSource,
|
||||||
Does.Contain(
|
Does.Contain("ResolveReferencedAssembly(string assemblyName)"));
|
||||||
"RegisterRemainingReflectedHandlerInterfaces(services, logger, implementationType0, knownServiceTypes0);"));
|
|
||||||
Assert.That(
|
Assert.That(
|
||||||
generatedSource,
|
generatedSource,
|
||||||
Does.Contain("if (knownServiceTypes.Contains(handlerInterface))"));
|
Does.Not.Contain("knownServiceTypes0"));
|
||||||
Assert.That(
|
Assert.That(
|
||||||
generatedSource,
|
generatedSource,
|
||||||
Does.Contain(
|
Does.Not.Contain("RegisterRemainingReflectedHandlerInterfaces"));
|
||||||
"Registered CQRS handler TestApp.DerivedHandler as GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<Dep.VisibleRequest, string>."));
|
|
||||||
Assert.That(
|
Assert.That(
|
||||||
generatedSource,
|
generatedSource,
|
||||||
Does.Not.Contain(
|
Does.Not.Contain(
|
||||||
"typeof(global::GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<global::Dep.VisibilityScope.ProtectedRequest"));
|
"// Remaining runtime interface discovery target:"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\GFramework.SourceGenerators\GFramework.SourceGenerators.csproj"/>
|
<ProjectReference Include="..\GFramework.Core.SourceGenerators\GFramework.Core.SourceGenerators.csproj"/>
|
||||||
|
<ProjectReference Include="..\GFramework.Cqrs.SourceGenerators\GFramework.Cqrs.SourceGenerators.csproj"/>
|
||||||
|
<ProjectReference Include="..\GFramework.Game.SourceGenerators\GFramework.Game.SourceGenerators.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -29,21 +29,25 @@
|
|||||||
<None Remove="GFramework.Core\**"/>
|
<None Remove="GFramework.Core\**"/>
|
||||||
<None Remove="GFramework.Game\**"/>
|
<None Remove="GFramework.Game\**"/>
|
||||||
<None Remove="GFramework.Godot\**"/>
|
<None Remove="GFramework.Godot\**"/>
|
||||||
<None Update="GFramework.SourceGenerators\logging\README.md">
|
<None Update="GFramework.Core.SourceGenerators\logging\README.md">
|
||||||
<Link>GFramework.SorceGenerators\logging\README.md</Link>
|
<Link>GFramework.SorceGenerators\logging\README.md</Link>
|
||||||
</None>
|
</None>
|
||||||
<None Update="GFramework.SourceGenerators\README.md">
|
<None Update="GFramework.Core.SourceGenerators\README.md">
|
||||||
<Link>GFramework.SorceGenerators\README.md</Link>
|
<Link>GFramework.SorceGenerators\README.md</Link>
|
||||||
</None>
|
</None>
|
||||||
<None Update="GFramework.SourceGenerators\AnalyzerReleases.Shipped.md">
|
<None Update="GFramework.Core.SourceGenerators\AnalyzerReleases.Shipped.md">
|
||||||
<Link>GFramework.SorceGenerators\AnalyzerReleases.Shipped.md</Link>
|
<Link>GFramework.SorceGenerators\AnalyzerReleases.Shipped.md</Link>
|
||||||
</None>
|
</None>
|
||||||
<None Update="GFramework.SourceGenerators\AnalyzerReleases.Unshipped.md">
|
<None Update="GFramework.Core.SourceGenerators\AnalyzerReleases.Unshipped.md">
|
||||||
<Link>GFramework.SorceGenerators\AnalyzerReleases.Unshipped.md</Link>
|
<Link>GFramework.SorceGenerators\AnalyzerReleases.Unshipped.md</Link>
|
||||||
</None>
|
</None>
|
||||||
<None Remove="GFramework.Godot.SourceGenerators\**"/>
|
<None Remove="GFramework.Godot.SourceGenerators\**"/>
|
||||||
<None Remove="GFramework.SorceGenerators\**"/>
|
<None Remove="GFramework.SorceGenerators\**"/>
|
||||||
<None Remove="GFramework.SourceGenerators\**"/>
|
<None Remove="GFramework.SourceGenerators\**"/>
|
||||||
|
<None Remove="GFramework.Core.SourceGenerators\**"/>
|
||||||
|
<None Remove="GFramework.Core.SourceGenerators.Abstractions\**"/>
|
||||||
|
<None Remove="GFramework.Cqrs.SourceGenerators\**"/>
|
||||||
|
<None Remove="GFramework.Game.SourceGenerators\**"/>
|
||||||
<None Remove="GFramework.SourceGenerators.Common\**"/>
|
<None Remove="GFramework.SourceGenerators.Common\**"/>
|
||||||
<None Remove="GFramework.SourceGenerators.Tests\**"/>
|
<None Remove="GFramework.SourceGenerators.Tests\**"/>
|
||||||
<None Remove="GFramework.Godot.SourceGenerators.Tests\**"/>
|
<None Remove="GFramework.Godot.SourceGenerators.Tests\**"/>
|
||||||
@ -77,18 +81,22 @@
|
|||||||
<Compile Remove="GFramework.Core\**"/>
|
<Compile Remove="GFramework.Core\**"/>
|
||||||
<Compile Remove="GFramework.Game\**"/>
|
<Compile Remove="GFramework.Game\**"/>
|
||||||
<Compile Remove="GFramework.Godot\**"/>
|
<Compile Remove="GFramework.Godot\**"/>
|
||||||
<Compile Update="GFramework.SourceGenerators\enums\EnumExtensionsGenerator.cs">
|
<Compile Update="GFramework.Core.SourceGenerators\enums\EnumExtensionsGenerator.cs">
|
||||||
<Link>GFramework.SorceGenerators\enums\EnumExtensionsGenerator.cs</Link>
|
<Link>GFramework.SorceGenerators\enums\EnumExtensionsGenerator.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Update="GFramework.SourceGenerators\logging\Diagnostic.cs">
|
<Compile Update="GFramework.Core.SourceGenerators\logging\Diagnostic.cs">
|
||||||
<Link>GFramework.SorceGenerators\logging\Diagnostic.cs</Link>
|
<Link>GFramework.SorceGenerators\logging\Diagnostic.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Update="GFramework.SourceGenerators\logging\LoggerGenerator.cs">
|
<Compile Update="GFramework.Core.SourceGenerators\logging\LoggerGenerator.cs">
|
||||||
<Link>GFramework.SorceGenerators\logging\LoggerGenerator.cs</Link>
|
<Link>GFramework.SorceGenerators\logging\LoggerGenerator.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Remove="GFramework.Godot.SourceGenerators\**"/>
|
<Compile Remove="GFramework.Godot.SourceGenerators\**"/>
|
||||||
<Compile Remove="GFramework.SorceGenerators\**"/>
|
<Compile Remove="GFramework.SorceGenerators\**"/>
|
||||||
<Compile Remove="GFramework.SourceGenerators\**"/>
|
<Compile Remove="GFramework.SourceGenerators\**"/>
|
||||||
|
<Compile Remove="GFramework.Core.SourceGenerators\**"/>
|
||||||
|
<Compile Remove="GFramework.Core.SourceGenerators.Abstractions\**"/>
|
||||||
|
<Compile Remove="GFramework.Cqrs.SourceGenerators\**"/>
|
||||||
|
<Compile Remove="GFramework.Game.SourceGenerators\**"/>
|
||||||
<Compile Remove="GFramework.SourceGenerators.Common\**"/>
|
<Compile Remove="GFramework.SourceGenerators.Common\**"/>
|
||||||
<Compile Remove="GFramework.SourceGenerators.Tests\**"/>
|
<Compile Remove="GFramework.SourceGenerators.Tests\**"/>
|
||||||
<Compile Remove="GFramework.Godot.SourceGenerators.Tests\**"/>
|
<Compile Remove="GFramework.Godot.SourceGenerators.Tests\**"/>
|
||||||
@ -120,6 +128,10 @@
|
|||||||
<EmbeddedResource Remove="GFramework.Godot.SourceGenerators\**"/>
|
<EmbeddedResource Remove="GFramework.Godot.SourceGenerators\**"/>
|
||||||
<EmbeddedResource Remove="GFramework.SorceGenerators\**"/>
|
<EmbeddedResource Remove="GFramework.SorceGenerators\**"/>
|
||||||
<EmbeddedResource Remove="GFramework.SourceGenerators\**"/>
|
<EmbeddedResource Remove="GFramework.SourceGenerators\**"/>
|
||||||
|
<EmbeddedResource Remove="GFramework.Core.SourceGenerators\**"/>
|
||||||
|
<EmbeddedResource Remove="GFramework.Core.SourceGenerators.Abstractions\**"/>
|
||||||
|
<EmbeddedResource Remove="GFramework.Cqrs.SourceGenerators\**"/>
|
||||||
|
<EmbeddedResource Remove="GFramework.Game.SourceGenerators\**"/>
|
||||||
<EmbeddedResource Remove="GFramework.SourceGenerators.Common\**"/>
|
<EmbeddedResource Remove="GFramework.SourceGenerators.Common\**"/>
|
||||||
<EmbeddedResource Remove="GFramework.SourceGenerators.Tests\**"/>
|
<EmbeddedResource Remove="GFramework.SourceGenerators.Tests\**"/>
|
||||||
<EmbeddedResource Remove="GFramework.Godot.SourceGenerators.Tests\**"/>
|
<EmbeddedResource Remove="GFramework.Godot.SourceGenerators.Tests\**"/>
|
||||||
|
|||||||
@ -2,10 +2,6 @@
|
|||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework", "GFramework.csproj", "{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework", "GFramework.csproj", "{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.SourceGenerators", "GFramework.SourceGenerators\GFramework.SourceGenerators.csproj", "{E9D51809-0351-4B83-B85B-B5F469AAB3B8}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.SourceGenerators.Abstractions", "GFramework.SourceGenerators.Abstractions\GFramework.SourceGenerators.Abstractions.csproj", "{84C5C3C9-5620-4924-BA04-92F813F2B70F}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Core", "GFramework.Core\GFramework.Core.csproj", "{A6D5854D-79EA-487A-9ED9-396E6A1F8031}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Core", "GFramework.Core\GFramework.Core.csproj", "{A6D5854D-79EA-487A-9ED9-396E6A1F8031}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Godot", "GFramework.Godot\GFramework.Godot.csproj", "{FC56D81A-3A3B-4B49-B318-363DFA0D8206}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Godot", "GFramework.Godot\GFramework.Godot.csproj", "{FC56D81A-3A3B-4B49-B318-363DFA0D8206}"
|
||||||
@ -46,6 +42,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Cqrs.Tests", "GF
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Tests.Common", "GFramework.Tests.Common\GFramework.Tests.Common.csproj", "{1100EE3E-A12D-4DE5-ABA8-591D3126570B}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Tests.Common", "GFramework.Tests.Common\GFramework.Tests.Common.csproj", "{1100EE3E-A12D-4DE5-ABA8-591D3126570B}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Core.SourceGenerators", "GFramework.Core.SourceGenerators\GFramework.Core.SourceGenerators.csproj", "{2E8A4BB6-DA58-484F-ACC5-A8F2FA885B36}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Core.SourceGenerators.Abstractions", "GFramework.Core.SourceGenerators.Abstractions\GFramework.Core.SourceGenerators.Abstractions.csproj", "{8858F489-4EDD-41F1-9A74-1CA1CB287EB4}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Cqrs.SourceGenerators", "GFramework.Cqrs.SourceGenerators\GFramework.Cqrs.SourceGenerators.csproj", "{3FDCD803-604F-48D9-B2A8-2EC621E8D598}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Game.SourceGenerators", "GFramework.Game.SourceGenerators\GFramework.Game.SourceGenerators.csproj", "{9D3AADF0-55E6-4F80-B9C5-875F63E170D8}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -68,30 +72,6 @@ Global
|
|||||||
{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Release|x64.Build.0 = Release|Any CPU
|
{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Release|x86.ActiveCfg = Release|Any CPU
|
{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Release|x86.Build.0 = Release|Any CPU
|
{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Debug|x64.ActiveCfg = Debug|Any CPU
|
{A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
@ -332,6 +312,54 @@ Global
|
|||||||
{1100EE3E-A12D-4DE5-ABA8-591D3126570B}.Release|x64.Build.0 = Release|Any CPU
|
{1100EE3E-A12D-4DE5-ABA8-591D3126570B}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{1100EE3E-A12D-4DE5-ABA8-591D3126570B}.Release|x86.ActiveCfg = Release|Any CPU
|
{1100EE3E-A12D-4DE5-ABA8-591D3126570B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{1100EE3E-A12D-4DE5-ABA8-591D3126570B}.Release|x86.Build.0 = Release|Any CPU
|
{1100EE3E-A12D-4DE5-ABA8-591D3126570B}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{2E8A4BB6-DA58-484F-ACC5-A8F2FA885B36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{2E8A4BB6-DA58-484F-ACC5-A8F2FA885B36}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2E8A4BB6-DA58-484F-ACC5-A8F2FA885B36}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{2E8A4BB6-DA58-484F-ACC5-A8F2FA885B36}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{2E8A4BB6-DA58-484F-ACC5-A8F2FA885B36}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{2E8A4BB6-DA58-484F-ACC5-A8F2FA885B36}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{2E8A4BB6-DA58-484F-ACC5-A8F2FA885B36}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{2E8A4BB6-DA58-484F-ACC5-A8F2FA885B36}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{2E8A4BB6-DA58-484F-ACC5-A8F2FA885B36}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{2E8A4BB6-DA58-484F-ACC5-A8F2FA885B36}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{2E8A4BB6-DA58-484F-ACC5-A8F2FA885B36}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{2E8A4BB6-DA58-484F-ACC5-A8F2FA885B36}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{8858F489-4EDD-41F1-9A74-1CA1CB287EB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{8858F489-4EDD-41F1-9A74-1CA1CB287EB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{8858F489-4EDD-41F1-9A74-1CA1CB287EB4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{8858F489-4EDD-41F1-9A74-1CA1CB287EB4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{8858F489-4EDD-41F1-9A74-1CA1CB287EB4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{8858F489-4EDD-41F1-9A74-1CA1CB287EB4}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{8858F489-4EDD-41F1-9A74-1CA1CB287EB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{8858F489-4EDD-41F1-9A74-1CA1CB287EB4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{8858F489-4EDD-41F1-9A74-1CA1CB287EB4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{8858F489-4EDD-41F1-9A74-1CA1CB287EB4}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{8858F489-4EDD-41F1-9A74-1CA1CB287EB4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{8858F489-4EDD-41F1-9A74-1CA1CB287EB4}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{3FDCD803-604F-48D9-B2A8-2EC621E8D598}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{3FDCD803-604F-48D9-B2A8-2EC621E8D598}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{3FDCD803-604F-48D9-B2A8-2EC621E8D598}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{3FDCD803-604F-48D9-B2A8-2EC621E8D598}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{3FDCD803-604F-48D9-B2A8-2EC621E8D598}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{3FDCD803-604F-48D9-B2A8-2EC621E8D598}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{3FDCD803-604F-48D9-B2A8-2EC621E8D598}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{3FDCD803-604F-48D9-B2A8-2EC621E8D598}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{3FDCD803-604F-48D9-B2A8-2EC621E8D598}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{3FDCD803-604F-48D9-B2A8-2EC621E8D598}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{3FDCD803-604F-48D9-B2A8-2EC621E8D598}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{3FDCD803-604F-48D9-B2A8-2EC621E8D598}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{9D3AADF0-55E6-4F80-B9C5-875F63E170D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{9D3AADF0-55E6-4F80-B9C5-875F63E170D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{9D3AADF0-55E6-4F80-B9C5-875F63E170D8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{9D3AADF0-55E6-4F80-B9C5-875F63E170D8}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{9D3AADF0-55E6-4F80-B9C5-875F63E170D8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{9D3AADF0-55E6-4F80-B9C5-875F63E170D8}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{9D3AADF0-55E6-4F80-B9C5-875F63E170D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{9D3AADF0-55E6-4F80-B9C5-875F63E170D8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{9D3AADF0-55E6-4F80-B9C5-875F63E170D8}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{9D3AADF0-55E6-4F80-B9C5-875F63E170D8}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{9D3AADF0-55E6-4F80-B9C5-875F63E170D8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{9D3AADF0-55E6-4F80-B9C5-875F63E170D8}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@ -246,9 +246,8 @@ public class GameArchitecture : Architecture
|
|||||||
优先使用程序集级生成注册器,失败时自动回退到反射扫描;如果同一程序集已经由默认路径或其他模块接入,框架会自动去重,避免重复注册
|
优先使用程序集级生成注册器,失败时自动回退到反射扫描;如果同一程序集已经由默认路径或其他模块接入,框架会自动去重,避免重复注册
|
||||||
handler。
|
handler。
|
||||||
|
|
||||||
`RegisterCqrsPipelineBehavior<TBehavior>()` 是推荐入口;旧的 `RegisterMediatorBehavior<TBehavior>()`
|
`RegisterCqrsPipelineBehavior<TBehavior>()` 是唯一保留的公开入口;旧的 `Mediator` 兼容别名与扩展已移除,不再继续维护。
|
||||||
仅作为兼容名称保留,当前已标记为 `Obsolete` 并从 IntelliSense 主路径隐藏,计划在未来 major 版本中移除。
|
当前接口支持两种形式:
|
||||||
`ContextAwareMediator*Extensions` 与 `MediatorCoroutineExtensions` 也遵循同样的弃用节奏。当前接口支持两种形式:
|
|
||||||
|
|
||||||
- 开放泛型行为,例如 `LoggingBehavior<,>`,用于匹配所有请求
|
- 开放泛型行为,例如 `LoggingBehavior<,>`,用于匹配所有请求
|
||||||
- 封闭行为类型,例如某个只服务于单一请求的 `SpecialBehavior`
|
- 封闭行为类型,例如某个只服务于单一请求的 `SpecialBehavior`
|
||||||
|
|||||||
@ -153,26 +153,29 @@ GameProject/
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\GFramework.Game\GFramework.Game.csproj" />
|
<ProjectReference Include="..\GFramework.Game\GFramework.Game.csproj" />
|
||||||
<ProjectReference Include="..\GFramework.SourceGenerators.Abstractions\GFramework.SourceGenerators.Abstractions.csproj"
|
<ProjectReference Include="..\GFramework.Core.SourceGenerators.Abstractions\GFramework.Core.SourceGenerators.Abstractions.csproj" />
|
||||||
OutputItemType="Analyzer"
|
|
||||||
ReferenceOutputAssembly="false" />
|
|
||||||
<ProjectReference Include="..\GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj"
|
<ProjectReference Include="..\GFramework.SourceGenerators.Common\GFramework.SourceGenerators.Common.csproj"
|
||||||
OutputItemType="Analyzer"
|
OutputItemType="Analyzer"
|
||||||
ReferenceOutputAssembly="false" />
|
ReferenceOutputAssembly="false" />
|
||||||
<ProjectReference Include="..\GFramework.SourceGenerators\GFramework.SourceGenerators.csproj"
|
<ProjectReference Include="..\GFramework.Core.SourceGenerators\GFramework.Core.SourceGenerators.csproj"
|
||||||
|
OutputItemType="Analyzer"
|
||||||
|
ReferenceOutputAssembly="false" />
|
||||||
|
<ProjectReference Include="..\GFramework.Game.SourceGenerators\GFramework.Game.SourceGenerators.csproj"
|
||||||
OutputItemType="Analyzer"
|
OutputItemType="Analyzer"
|
||||||
ReferenceOutputAssembly="false" />
|
ReferenceOutputAssembly="false" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Import Project="..\GFramework.SourceGenerators\GeWuYou.GFramework.SourceGenerators.targets" />
|
<Import Project="..\GFramework.Game.SourceGenerators\GeWuYou.GFramework.Game.SourceGenerators.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
```
|
```
|
||||||
|
|
||||||
这段配置的作用:
|
这段配置的作用:
|
||||||
|
|
||||||
- `GFramework.Game` 提供运行时 `YamlConfigLoader`、`ConfigRegistry`、`GameConfigBootstrap`、`GameConfigModule` 和只读表实现
|
- `GFramework.Game` 提供运行时 `YamlConfigLoader`、`ConfigRegistry`、`GameConfigBootstrap`、`GameConfigModule` 和只读表实现
|
||||||
- 三个 `ProjectReference(... OutputItemType="Analyzer")` 把生成器接进当前消费者项目
|
- `GFramework.Core.SourceGenerators.Abstractions` 提供 `Core` 侧 source-generator attributes
|
||||||
- `GeWuYou.GFramework.SourceGenerators.targets` 自动把 `schemas/**/*.schema.json` 加入 `AdditionalFiles`
|
- `GFramework.SourceGenerators.Common`、`GFramework.Core.SourceGenerators` 与 `GFramework.Game.SourceGenerators`
|
||||||
|
共同把生成器接进当前消费者项目
|
||||||
|
- `GeWuYou.GFramework.Game.SourceGenerators.targets` 自动把 `schemas/**/*.schema.json` 加入 `AdditionalFiles`
|
||||||
|
|
||||||
如果你使用打包后的 NuGet,而不是仓库内项目引用,原则保持不变:
|
如果你使用打包后的 NuGet,而不是仓库内项目引用,原则保持不变:
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user