mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-13 14:14:29 +08:00
feat(cqrs): 添加CQRS运行时模块和兼容性扩展
- 新增ContextAwareMediatorCommandExtensions提供命令扩展方法的兼容性别名 - 新增ContextAwareMediatorExtensions提供CQRS统一接口扩展方法的兼容性别名 - 新增ContextAwareMediatorQueryExtensions提供查询扩展方法的兼容性别名 - 添加CqrsRuntimeModule用于注册CQRS运行时和处理器注册器到依赖注入容器 - 更新IArchitectureContext接口添加新版CQRS请求、命令、查询和通知的统一入口 - 添加架构上下文的CQRS处理器注册相关单元测试 - 配置项目文件以支持多目标框架和包引用管理
This commit is contained in:
parent
f7b4ae9995
commit
a80ff59631
@ -15,7 +15,7 @@ namespace GFramework.Core.Abstractions.Architectures;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <para>旧的 <c>GFramework.Core.Abstractions.Command</c> 与 <c>GFramework.Core.Abstractions.Query</c> 契约会继续通过原有 Command/Query Executor 路径执行,以保证存量代码兼容。</para>
|
/// <para>旧的 <c>GFramework.Core.Abstractions.Command</c> 与 <c>GFramework.Core.Abstractions.Query</c> 契约会继续通过原有 Command/Query Executor 路径执行,以保证存量代码兼容。</para>
|
||||||
/// <para>新的 <c>GFramework.Core.Abstractions.Cqrs</c> 契约由内置 CQRS dispatcher 统一处理,支持 request pipeline、notification publish 与 stream request。</para>
|
/// <para>新的 <c>GFramework.Cqrs.Abstractions.Cqrs</c> 契约由内置 CQRS dispatcher 统一处理,支持 request pipeline、notification publish 与 stream request。</para>
|
||||||
/// <para>新功能优先使用 <see cref="SendRequestAsync{TResponse}(IRequest{TResponse},CancellationToken)" />、<see cref="SendAsync{TCommand}(TCommand,CancellationToken)" /> 与对应的 CQRS Command/Query 重载;迁移旧代码时可先保留旧入口,再逐步替换为 CQRS 请求模型。</para>
|
/// <para>新功能优先使用 <see cref="SendRequestAsync{TResponse}(IRequest{TResponse},CancellationToken)" />、<see cref="SendAsync{TCommand}(TCommand,CancellationToken)" /> 与对应的 CQRS Command/Query 重载;迁移旧代码时可先保留旧入口,再逐步替换为 CQRS 请求模型。</para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public interface IArchitectureContext
|
public interface IArchitectureContext
|
||||||
@ -175,7 +175,7 @@ public interface IArchitectureContext
|
|||||||
/// <param name="query">要发送的 CQRS 查询。</param>
|
/// <param name="query">要发送的 CQRS 查询。</param>
|
||||||
/// <returns>查询结果。</returns>
|
/// <returns>查询结果。</returns>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 这是迁移后的推荐查询入口。新查询应优先实现 <c>GFramework.Core.Abstractions.Cqrs.Query.IQuery<TResponse></c>。
|
/// 这是迁移后的推荐查询入口。新查询应优先实现 <c>GFramework.Cqrs.Abstractions.Cqrs.Query.IQuery<TResponse></c>。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
TResponse SendQuery<TResponse>(GFramework.Cqrs.Abstractions.Cqrs.Query.IQuery<TResponse> query);
|
TResponse SendQuery<TResponse>(GFramework.Cqrs.Abstractions.Cqrs.Query.IQuery<TResponse> query);
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using GFramework.Core.Abstractions.Cqrs;
|
|
||||||
using GFramework.Core.Abstractions.Logging;
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Architectures;
|
using GFramework.Core.Architectures;
|
||||||
using GFramework.Core.Logging;
|
using GFramework.Core.Logging;
|
||||||
|
using GFramework.Cqrs;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
|
||||||
namespace GFramework.Core.Tests.Architectures;
|
namespace GFramework.Core.Tests.Architectures;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using GFramework.Core.Abstractions.Rule;
|
using GFramework.Core.Abstractions.Rule;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs.Command;
|
using GFramework.Cqrs.Abstractions.Cqrs.Command;
|
||||||
|
using GFramework.Cqrs.Extensions;
|
||||||
|
|
||||||
namespace GFramework.Core.Extensions;
|
namespace GFramework.Core.Extensions;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using GFramework.Core.Abstractions.Rule;
|
using GFramework.Core.Abstractions.Rule;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
using GFramework.Cqrs.Extensions;
|
||||||
|
|
||||||
namespace GFramework.Core.Extensions;
|
namespace GFramework.Core.Extensions;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using GFramework.Core.Abstractions.Rule;
|
using GFramework.Core.Abstractions.Rule;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs.Query;
|
using GFramework.Cqrs.Abstractions.Cqrs.Query;
|
||||||
|
using GFramework.Cqrs.Extensions;
|
||||||
|
|
||||||
namespace GFramework.Core.Extensions;
|
namespace GFramework.Core.Extensions;
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\GFramework.Cqrs.Abstractions\GFramework.Cqrs.Abstractions.csproj"/>
|
<ProjectReference Include="..\GFramework.Cqrs.Abstractions\GFramework.Cqrs.Abstractions.csproj"/>
|
||||||
|
<ProjectReference Include="..\GFramework.Cqrs\GFramework.Cqrs.csproj"/>
|
||||||
<ProjectReference Include="..\$(AssemblyName).Abstractions\$(AssemblyName).Abstractions.csproj"/>
|
<ProjectReference Include="..\$(AssemblyName).Abstractions\$(AssemblyName).Abstractions.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
using GFramework.Core.Abstractions.Architectures;
|
using GFramework.Core.Abstractions.Architectures;
|
||||||
using GFramework.Core.Abstractions.Cqrs;
|
using GFramework.Core.Abstractions.Cqrs;
|
||||||
using GFramework.Core.Abstractions.Ioc;
|
using GFramework.Core.Abstractions.Ioc;
|
||||||
using GFramework.Core.Cqrs.Internal;
|
|
||||||
using GFramework.Core.Logging;
|
using GFramework.Core.Logging;
|
||||||
|
using GFramework.Cqrs;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
|
||||||
namespace GFramework.Core.Services.Modules;
|
namespace GFramework.Core.Services.Modules;
|
||||||
@ -37,11 +37,12 @@ public sealed class CqrsRuntimeModule : IServiceModule
|
|||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(container);
|
ArgumentNullException.ThrowIfNull(container);
|
||||||
|
|
||||||
var dispatcherLogger = LoggerFactoryResolver.Provider.CreateLogger(nameof(CqrsDispatcher));
|
var dispatcherLogger = LoggerFactoryResolver.Provider.CreateLogger("CqrsDispatcher");
|
||||||
var registrarLogger = LoggerFactoryResolver.Provider.CreateLogger(nameof(DefaultCqrsHandlerRegistrar));
|
var registrarLogger = LoggerFactoryResolver.Provider.CreateLogger("DefaultCqrsHandlerRegistrar");
|
||||||
|
|
||||||
container.Register<ICqrsRuntime>(new CqrsDispatcher(container, dispatcherLogger));
|
container.Register<ICqrsRuntime>(CqrsRuntimeFactory.CreateRuntime(container, dispatcherLogger));
|
||||||
container.Register<ICqrsHandlerRegistrar>(new DefaultCqrsHandlerRegistrar(container, registrarLogger));
|
container.Register<ICqrsHandlerRegistrar>(
|
||||||
|
CqrsRuntimeFactory.CreateHandlerRegistrar(container, registrarLogger));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
using GFramework.Core.Abstractions.Cqrs;
|
|
||||||
using GFramework.Core.Abstractions.Logging;
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Architectures;
|
using GFramework.Core.Architectures;
|
||||||
using GFramework.Core.Ioc;
|
using GFramework.Core.Ioc;
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs.Command;
|
using GFramework.Cqrs.Abstractions.Cqrs.Command;
|
||||||
|
|
||||||
namespace GFramework.Core.Cqrs.Command;
|
namespace GFramework.Cqrs.Command;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 表示一个基础命令类,用于处理带有输入和响应的命令模式实现。
|
/// 表示一个基础命令类,用于处理带有输入和响应的命令模式实现。
|
||||||
@ -1,4 +1,4 @@
|
|||||||
namespace GFramework.Core.Abstractions.Cqrs;
|
namespace GFramework.Cqrs;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 声明程序集内可供运行时直接调用的 CQRS 处理器注册器类型。
|
/// 声明程序集内可供运行时直接调用的 CQRS 处理器注册器类型。
|
||||||
45
GFramework.Cqrs/CqrsRuntimeFactory.cs
Normal file
45
GFramework.Cqrs/CqrsRuntimeFactory.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using GFramework.Core.Abstractions.Cqrs;
|
||||||
|
using GFramework.Core.Abstractions.Ioc;
|
||||||
|
using GFramework.Core.Abstractions.Logging;
|
||||||
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
using GFramework.Cqrs.Internal;
|
||||||
|
|
||||||
|
namespace GFramework.Cqrs;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 提供 CQRS runtime 默认实现的跨程序集创建入口。
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <see cref="GFramework.Core" /> 需要在不暴露内部实现细节的前提下接入默认 CQRS runtime,
|
||||||
|
/// 因此通过该工厂返回抽象接口,而不是直接公开内部 dispatcher / registrar 类型。
|
||||||
|
/// </remarks>
|
||||||
|
public static class CqrsRuntimeFactory
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 创建默认 CQRS runtime 分发器。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="container">目标依赖注入容器。</param>
|
||||||
|
/// <param name="logger">用于 runtime 诊断的日志器。</param>
|
||||||
|
/// <returns>默认 CQRS runtime。</returns>
|
||||||
|
public static ICqrsRuntime CreateRuntime(IIocContainer container, ILogger logger)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(container);
|
||||||
|
ArgumentNullException.ThrowIfNull(logger);
|
||||||
|
|
||||||
|
return new CqrsDispatcher(container, logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建默认 CQRS 处理器注册器。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="container">目标依赖注入容器。</param>
|
||||||
|
/// <param name="logger">用于注册阶段诊断的日志器。</param>
|
||||||
|
/// <returns>默认 CQRS handler registrar。</returns>
|
||||||
|
public static ICqrsHandlerRegistrar CreateHandlerRegistrar(IIocContainer container, ILogger logger)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(container);
|
||||||
|
ArgumentNullException.ThrowIfNull(logger);
|
||||||
|
|
||||||
|
return new DefaultCqrsHandlerRegistrar(container, logger);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
using GFramework.Core.Abstractions.Rule;
|
using GFramework.Core.Abstractions.Rule;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs.Command;
|
using GFramework.Cqrs.Abstractions.Cqrs.Command;
|
||||||
|
|
||||||
namespace GFramework.Core.Extensions;
|
namespace GFramework.Cqrs.Extensions;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 提供对 <see cref="IContextAware" /> 接口的 CQRS 命令扩展方法。
|
/// 提供对 <see cref="IContextAware" /> 接口的 CQRS 命令扩展方法。
|
||||||
@ -1,7 +1,7 @@
|
|||||||
using GFramework.Core.Abstractions.Rule;
|
using GFramework.Core.Abstractions.Rule;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
|
||||||
namespace GFramework.Core.Extensions;
|
namespace GFramework.Cqrs.Extensions;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 提供对 <see cref="IContextAware" /> 接口的 CQRS 统一扩展方法。
|
/// 提供对 <see cref="IContextAware" /> 接口的 CQRS 统一扩展方法。
|
||||||
@ -1,7 +1,7 @@
|
|||||||
using GFramework.Core.Abstractions.Rule;
|
using GFramework.Core.Abstractions.Rule;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs.Query;
|
using GFramework.Cqrs.Abstractions.Cqrs.Query;
|
||||||
|
|
||||||
namespace GFramework.Core.Extensions;
|
namespace GFramework.Cqrs.Extensions;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 提供对 <see cref="IContextAware" /> 接口的 CQRS 查询扩展方法。
|
/// 提供对 <see cref="IContextAware" /> 接口的 CQRS 查询扩展方法。
|
||||||
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\GFramework.Cqrs.Abstractions\GFramework.Cqrs.Abstractions.csproj"/>
|
<ProjectReference Include="..\GFramework.Cqrs.Abstractions\GFramework.Cqrs.Abstractions.csproj"/>
|
||||||
|
<ProjectReference Include="..\GFramework.Core.Abstractions\GFramework.Core.Abstractions.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
6
GFramework.Cqrs/GlobalUsings.cs
Normal file
6
GFramework.Cqrs/GlobalUsings.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
global using System;
|
||||||
|
global using System.Collections.Generic;
|
||||||
|
global using System.Linq;
|
||||||
|
global using System.Threading;
|
||||||
|
global using System.Threading.Tasks;
|
||||||
|
global using Microsoft.Extensions.DependencyInjection;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
using GFramework.Core.Abstractions.Logging;
|
using GFramework.Core.Abstractions.Logging;
|
||||||
|
|
||||||
namespace GFramework.Core.Abstractions.Cqrs;
|
namespace GFramework.Cqrs;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 定义由源码生成器产出的 CQRS 处理器注册器契约。
|
/// 定义由源码生成器产出的 CQRS 处理器注册器契约。
|
||||||
@ -7,7 +7,7 @@ using GFramework.Core.Abstractions.Logging;
|
|||||||
using GFramework.Core.Abstractions.Rule;
|
using GFramework.Core.Abstractions.Rule;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
|
||||||
namespace GFramework.Core.Cqrs.Internal;
|
namespace GFramework.Cqrs.Internal;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GFramework 自有 CQRS 运行时分发器。
|
/// GFramework 自有 CQRS 运行时分发器。
|
||||||
@ -1,10 +1,9 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using GFramework.Core.Abstractions.Cqrs;
|
|
||||||
using GFramework.Core.Abstractions.Ioc;
|
using GFramework.Core.Abstractions.Ioc;
|
||||||
using GFramework.Core.Abstractions.Logging;
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
|
||||||
namespace GFramework.Core.Cqrs.Internal;
|
namespace GFramework.Cqrs.Internal;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 在架构初始化期间扫描并注册 CQRS 处理器。
|
/// 在架构初始化期间扫描并注册 CQRS 处理器。
|
||||||
@ -3,7 +3,7 @@ using GFramework.Core.Abstractions.Ioc;
|
|||||||
using GFramework.Core.Abstractions.Logging;
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
|
||||||
namespace GFramework.Core.Cqrs.Internal;
|
namespace GFramework.Cqrs.Internal;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认的 CQRS 处理器注册器实现。
|
/// 默认的 CQRS 处理器注册器实现。
|
||||||
@ -14,7 +14,7 @@
|
|||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs.Notification;
|
using GFramework.Cqrs.Abstractions.Cqrs.Notification;
|
||||||
|
|
||||||
namespace GFramework.Core.Cqrs.Notification;
|
namespace GFramework.Cqrs.Notification;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 表示一个基础通知类,用于处理带有输入的通知模式实现。
|
/// 表示一个基础通知类,用于处理带有输入的通知模式实现。
|
||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs.Query;
|
using GFramework.Cqrs.Abstractions.Cqrs.Query;
|
||||||
|
|
||||||
namespace GFramework.Core.Cqrs.Query;
|
namespace GFramework.Cqrs.Query;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 表示一个基础查询类,用于处理带有输入和响应的查询模式实现。
|
/// 表示一个基础查询类,用于处理带有输入和响应的查询模式实现。
|
||||||
@ -14,7 +14,7 @@
|
|||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs.Request;
|
using GFramework.Cqrs.Abstractions.Cqrs.Request;
|
||||||
|
|
||||||
namespace GFramework.Core.Cqrs.Request;
|
namespace GFramework.Cqrs.Request;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 表示一个基础请求类,用于处理带有输入和响应的请求模式实现。
|
/// 表示一个基础请求类,用于处理带有输入和响应的请求模式实现。
|
||||||
@ -1,10 +1,10 @@
|
|||||||
using GFramework.Core.Abstractions.Rule;
|
using GFramework.Core.Abstractions.Rule;
|
||||||
using GFramework.Core.Coroutine;
|
using GFramework.Core.Coroutine;
|
||||||
using GFramework.Core.Coroutine.Extensions;
|
using GFramework.Core.Coroutine.Extensions;
|
||||||
using GFramework.Core.Extensions;
|
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs.Command;
|
using GFramework.Cqrs.Abstractions.Cqrs.Command;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs.Query;
|
using GFramework.Cqrs.Abstractions.Cqrs.Query;
|
||||||
|
using GFramework.Cqrs.Extensions;
|
||||||
|
|
||||||
namespace GFramework.Godot.Coroutine;
|
namespace GFramework.Godot.Coroutine;
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,11 @@ public static class PathContests
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const string CoreNamespace = $"{BaseNamespace}.Core";
|
public const string CoreNamespace = $"{BaseNamespace}.Core";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GFramework CQRS runtime 命名空间
|
||||||
|
/// </summary>
|
||||||
|
public const string CqrsNamespace = $"{BaseNamespace}.Cqrs";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GFramework Godot模块命名空间
|
/// GFramework Godot模块命名空间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -45,4 +50,9 @@ public static class PathContests
|
|||||||
/// GFramework核心抽象层命名空间
|
/// GFramework核心抽象层命名空间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string CoreAbstractionsNamespace = $"{CoreNamespace}.Abstractions";
|
public const string CoreAbstractionsNamespace = $"{CoreNamespace}.Abstractions";
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
|
/// GFramework CQRS 抽象层命名空间
|
||||||
|
/// </summary>
|
||||||
|
public const string CqrsAbstractionsNamespace = $"{CqrsNamespace}.Abstractions";
|
||||||
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ public class CqrsHandlerRegistryGeneratorTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace GFramework.Core.Abstractions.Cqrs
|
namespace GFramework.Cqrs.Abstractions.Cqrs
|
||||||
{
|
{
|
||||||
public interface IRequest<TResponse> { }
|
public interface IRequest<TResponse> { }
|
||||||
public interface INotification { }
|
public interface INotification { }
|
||||||
@ -47,7 +47,10 @@ public class CqrsHandlerRegistryGeneratorTests
|
|||||||
public interface IRequestHandler<in TRequest, TResponse> where TRequest : IRequest<TResponse> { }
|
public interface IRequestHandler<in TRequest, TResponse> where TRequest : IRequest<TResponse> { }
|
||||||
public interface INotificationHandler<in TNotification> where TNotification : INotification { }
|
public interface INotificationHandler<in TNotification> where TNotification : INotification { }
|
||||||
public interface IStreamRequestHandler<in TRequest, out TResponse> where TRequest : IStreamRequest<TResponse> { }
|
public interface IStreamRequestHandler<in TRequest, out TResponse> where TRequest : IStreamRequest<TResponse> { }
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace GFramework.Cqrs
|
||||||
|
{
|
||||||
public interface ICqrsHandlerRegistry
|
public interface ICqrsHandlerRegistry
|
||||||
{
|
{
|
||||||
void Register(Microsoft.Extensions.DependencyInjection.IServiceCollection services, GFramework.Core.Abstractions.Logging.ILogger logger);
|
void Register(Microsoft.Extensions.DependencyInjection.IServiceCollection services, GFramework.Core.Abstractions.Logging.ILogger logger);
|
||||||
@ -62,7 +65,7 @@ public class CqrsHandlerRegistryGeneratorTests
|
|||||||
|
|
||||||
namespace TestApp
|
namespace TestApp
|
||||||
{
|
{
|
||||||
using GFramework.Core.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
|
||||||
public sealed record PingQuery() : IRequest<string>;
|
public sealed record PingQuery() : IRequest<string>;
|
||||||
public sealed record DomainEvent() : INotification;
|
public sealed record DomainEvent() : INotification;
|
||||||
@ -78,11 +81,11 @@ public class CqrsHandlerRegistryGeneratorTests
|
|||||||
// <auto-generated />
|
// <auto-generated />
|
||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
[assembly: global::GFramework.Core.Abstractions.Cqrs.CqrsHandlerRegistryAttribute(typeof(global::GFramework.Generated.Cqrs.__GFrameworkGeneratedCqrsHandlerRegistry))]
|
[assembly: global::GFramework.Cqrs.CqrsHandlerRegistryAttribute(typeof(global::GFramework.Generated.Cqrs.__GFrameworkGeneratedCqrsHandlerRegistry))]
|
||||||
|
|
||||||
namespace GFramework.Generated.Cqrs;
|
namespace GFramework.Generated.Cqrs;
|
||||||
|
|
||||||
internal sealed class __GFrameworkGeneratedCqrsHandlerRegistry : global::GFramework.Core.Abstractions.Cqrs.ICqrsHandlerRegistry
|
internal sealed class __GFrameworkGeneratedCqrsHandlerRegistry : global::GFramework.Cqrs.ICqrsHandlerRegistry
|
||||||
{
|
{
|
||||||
public void Register(global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::GFramework.Core.Abstractions.Logging.ILogger logger)
|
public void Register(global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::GFramework.Core.Abstractions.Logging.ILogger logger)
|
||||||
{
|
{
|
||||||
@ -93,19 +96,19 @@ public class CqrsHandlerRegistryGeneratorTests
|
|||||||
|
|
||||||
global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient(
|
global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient(
|
||||||
services,
|
services,
|
||||||
typeof(global::GFramework.Core.Abstractions.Cqrs.IRequestHandler<global::TestApp.PingQuery, string>),
|
typeof(global::GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<global::TestApp.PingQuery, string>),
|
||||||
typeof(global::TestApp.AlphaQueryHandler));
|
typeof(global::TestApp.AlphaQueryHandler));
|
||||||
logger.Debug("Registered CQRS handler TestApp.AlphaQueryHandler as GFramework.Core.Abstractions.Cqrs.IRequestHandler<TestApp.PingQuery, string>.");
|
logger.Debug("Registered CQRS handler TestApp.AlphaQueryHandler as GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<TestApp.PingQuery, string>.");
|
||||||
global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient(
|
global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient(
|
||||||
services,
|
services,
|
||||||
typeof(global::GFramework.Core.Abstractions.Cqrs.IStreamRequestHandler<global::TestApp.NumberStream, int>),
|
typeof(global::GFramework.Cqrs.Abstractions.Cqrs.IStreamRequestHandler<global::TestApp.NumberStream, int>),
|
||||||
typeof(global::TestApp.StreamHandler));
|
typeof(global::TestApp.StreamHandler));
|
||||||
logger.Debug("Registered CQRS handler TestApp.StreamHandler as GFramework.Core.Abstractions.Cqrs.IStreamRequestHandler<TestApp.NumberStream, int>.");
|
logger.Debug("Registered CQRS handler TestApp.StreamHandler as GFramework.Cqrs.Abstractions.Cqrs.IStreamRequestHandler<TestApp.NumberStream, int>.");
|
||||||
global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient(
|
global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient(
|
||||||
services,
|
services,
|
||||||
typeof(global::GFramework.Core.Abstractions.Cqrs.INotificationHandler<global::TestApp.DomainEvent>),
|
typeof(global::GFramework.Cqrs.Abstractions.Cqrs.INotificationHandler<global::TestApp.DomainEvent>),
|
||||||
typeof(global::TestApp.ZetaNotificationHandler));
|
typeof(global::TestApp.ZetaNotificationHandler));
|
||||||
logger.Debug("Registered CQRS handler TestApp.ZetaNotificationHandler as GFramework.Core.Abstractions.Cqrs.INotificationHandler<TestApp.DomainEvent>.");
|
logger.Debug("Registered CQRS handler TestApp.ZetaNotificationHandler as GFramework.Cqrs.Abstractions.Cqrs.INotificationHandler<TestApp.DomainEvent>.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +146,7 @@ public class CqrsHandlerRegistryGeneratorTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace GFramework.Core.Abstractions.Cqrs
|
namespace GFramework.Cqrs.Abstractions.Cqrs
|
||||||
{
|
{
|
||||||
public interface IRequest<TResponse> { }
|
public interface IRequest<TResponse> { }
|
||||||
public interface INotification { }
|
public interface INotification { }
|
||||||
@ -152,7 +155,10 @@ public class CqrsHandlerRegistryGeneratorTests
|
|||||||
public interface IRequestHandler<in TRequest, TResponse> where TRequest : IRequest<TResponse> { }
|
public interface IRequestHandler<in TRequest, TResponse> where TRequest : IRequest<TResponse> { }
|
||||||
public interface INotificationHandler<in TNotification> where TNotification : INotification { }
|
public interface INotificationHandler<in TNotification> where TNotification : INotification { }
|
||||||
public interface IStreamRequestHandler<in TRequest, out TResponse> where TRequest : IStreamRequest<TResponse> { }
|
public interface IStreamRequestHandler<in TRequest, out TResponse> where TRequest : IStreamRequest<TResponse> { }
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace GFramework.Cqrs
|
||||||
|
{
|
||||||
public interface ICqrsHandlerRegistry
|
public interface ICqrsHandlerRegistry
|
||||||
{
|
{
|
||||||
void Register(Microsoft.Extensions.DependencyInjection.IServiceCollection services, GFramework.Core.Abstractions.Logging.ILogger logger);
|
void Register(Microsoft.Extensions.DependencyInjection.IServiceCollection services, GFramework.Core.Abstractions.Logging.ILogger logger);
|
||||||
@ -167,7 +173,7 @@ public class CqrsHandlerRegistryGeneratorTests
|
|||||||
|
|
||||||
namespace TestApp
|
namespace TestApp
|
||||||
{
|
{
|
||||||
using GFramework.Core.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
|
||||||
public sealed record VisibleRequest() : IRequest<string>;
|
public sealed record VisibleRequest() : IRequest<string>;
|
||||||
|
|
||||||
|
|||||||
@ -8,13 +8,17 @@ namespace GFramework.SourceGenerators.Cqrs;
|
|||||||
[Generator]
|
[Generator]
|
||||||
public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
||||||
{
|
{
|
||||||
private const string CqrsNamespace = $"{PathContests.CoreAbstractionsNamespace}.Cqrs";
|
private const string CqrsContractsNamespace = $"{PathContests.CqrsAbstractionsNamespace}.Cqrs";
|
||||||
|
private const string CqrsRuntimeNamespace = PathContests.CqrsNamespace;
|
||||||
private const string LoggingNamespace = $"{PathContests.CoreAbstractionsNamespace}.Logging";
|
private const string LoggingNamespace = $"{PathContests.CoreAbstractionsNamespace}.Logging";
|
||||||
private const string IRequestHandlerMetadataName = $"{CqrsNamespace}.IRequestHandler`2";
|
private const string IRequestHandlerMetadataName = $"{CqrsContractsNamespace}.IRequestHandler`2";
|
||||||
private const string INotificationHandlerMetadataName = $"{CqrsNamespace}.INotificationHandler`1";
|
private const string INotificationHandlerMetadataName = $"{CqrsContractsNamespace}.INotificationHandler`1";
|
||||||
private const string IStreamRequestHandlerMetadataName = $"{CqrsNamespace}.IStreamRequestHandler`2";
|
private const string IStreamRequestHandlerMetadataName = $"{CqrsContractsNamespace}.IStreamRequestHandler`2";
|
||||||
private const string ICqrsHandlerRegistryMetadataName = $"{CqrsNamespace}.ICqrsHandlerRegistry";
|
private const string ICqrsHandlerRegistryMetadataName = $"{CqrsRuntimeNamespace}.ICqrsHandlerRegistry";
|
||||||
private const string CqrsHandlerRegistryAttributeMetadataName = $"{CqrsNamespace}.CqrsHandlerRegistryAttribute";
|
|
||||||
|
private const string CqrsHandlerRegistryAttributeMetadataName =
|
||||||
|
$"{CqrsRuntimeNamespace}.CqrsHandlerRegistryAttribute";
|
||||||
|
|
||||||
private const string ILoggerMetadataName = $"{LoggingNamespace}.ILogger";
|
private const string ILoggerMetadataName = $"{LoggingNamespace}.ILogger";
|
||||||
private const string IServiceCollectionMetadataName = "Microsoft.Extensions.DependencyInjection.IServiceCollection";
|
private const string IServiceCollectionMetadataName = "Microsoft.Extensions.DependencyInjection.IServiceCollection";
|
||||||
private const string GeneratedNamespace = "GFramework.Generated.Cqrs";
|
private const string GeneratedNamespace = "GFramework.Generated.Cqrs";
|
||||||
@ -273,7 +277,7 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
|||||||
builder.AppendLine("#nullable enable");
|
builder.AppendLine("#nullable enable");
|
||||||
builder.AppendLine();
|
builder.AppendLine();
|
||||||
builder.Append("[assembly: global::");
|
builder.Append("[assembly: global::");
|
||||||
builder.Append(CqrsNamespace);
|
builder.Append(CqrsRuntimeNamespace);
|
||||||
builder.Append(".CqrsHandlerRegistryAttribute(typeof(global::");
|
builder.Append(".CqrsHandlerRegistryAttribute(typeof(global::");
|
||||||
builder.Append(GeneratedNamespace);
|
builder.Append(GeneratedNamespace);
|
||||||
builder.Append('.');
|
builder.Append('.');
|
||||||
@ -287,7 +291,7 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
|||||||
builder.Append("internal sealed class ");
|
builder.Append("internal sealed class ");
|
||||||
builder.Append(GeneratedTypeName);
|
builder.Append(GeneratedTypeName);
|
||||||
builder.Append(" : global::");
|
builder.Append(" : global::");
|
||||||
builder.Append(CqrsNamespace);
|
builder.Append(CqrsRuntimeNamespace);
|
||||||
builder.AppendLine(".ICqrsHandlerRegistry");
|
builder.AppendLine(".ICqrsHandlerRegistry");
|
||||||
builder.AppendLine("{");
|
builder.AppendLine("{");
|
||||||
builder.Append(
|
builder.Append(
|
||||||
|
|||||||
@ -4,10 +4,11 @@ using System.Reflection;
|
|||||||
using GFramework.Core.Abstractions.Cqrs;
|
using GFramework.Core.Abstractions.Cqrs;
|
||||||
using GFramework.Core.Abstractions.Ioc;
|
using GFramework.Core.Abstractions.Ioc;
|
||||||
using GFramework.Core.Abstractions.Logging;
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Architectures;
|
|
||||||
using GFramework.Core.Ioc;
|
using GFramework.Core.Ioc;
|
||||||
using GFramework.Core.Logging;
|
using GFramework.Core.Logging;
|
||||||
|
using GFramework.Cqrs;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
using GFramework.Cqrs.Command;
|
||||||
|
|
||||||
namespace GFramework.Tests.Common;
|
namespace GFramework.Tests.Common;
|
||||||
|
|
||||||
@ -20,7 +21,9 @@ namespace GFramework.Tests.Common;
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static class CqrsTestRuntime
|
public static class CqrsTestRuntime
|
||||||
{
|
{
|
||||||
private static readonly Type CqrsHandlerRegistrarType = typeof(ArchitectureContext).Assembly
|
private static readonly Assembly CqrsRuntimeAssembly = typeof(CommandBase<,>).Assembly;
|
||||||
|
|
||||||
|
private static readonly Type CqrsHandlerRegistrarType = CqrsRuntimeAssembly
|
||||||
.GetType(
|
.GetType(
|
||||||
"GFramework.Core.Cqrs.Internal.CqrsHandlerRegistrar",
|
"GFramework.Core.Cqrs.Internal.CqrsHandlerRegistrar",
|
||||||
throwOnError: true)!;
|
throwOnError: true)!;
|
||||||
@ -40,41 +43,6 @@ public static class CqrsTestRuntime
|
|||||||
?? throw new InvalidOperationException(
|
?? throw new InvalidOperationException(
|
||||||
"Failed to locate CqrsHandlerRegistrar.RegisterHandlers.");
|
"Failed to locate CqrsHandlerRegistrar.RegisterHandlers.");
|
||||||
|
|
||||||
private static readonly Type CqrsDispatcherType = typeof(ArchitectureContext).Assembly
|
|
||||||
.GetType(
|
|
||||||
"GFramework.Core.Cqrs.Internal.CqrsDispatcher",
|
|
||||||
throwOnError: true)!;
|
|
||||||
|
|
||||||
private static readonly ConstructorInfo CqrsDispatcherConstructor = CqrsDispatcherType.GetConstructor(
|
|
||||||
BindingFlags.Instance |
|
|
||||||
BindingFlags.Public |
|
|
||||||
BindingFlags.NonPublic,
|
|
||||||
binder: null,
|
|
||||||
[
|
|
||||||
typeof(IIocContainer),
|
|
||||||
typeof(ILogger)
|
|
||||||
],
|
|
||||||
modifiers: null)
|
|
||||||
?? throw new InvalidOperationException(
|
|
||||||
"Failed to locate CqrsDispatcher constructor.");
|
|
||||||
|
|
||||||
private static readonly Type DefaultCqrsHandlerRegistrarType = typeof(ArchitectureContext).Assembly
|
|
||||||
.GetType(
|
|
||||||
"GFramework.Core.Cqrs.Internal.DefaultCqrsHandlerRegistrar",
|
|
||||||
throwOnError: true)!;
|
|
||||||
|
|
||||||
private static readonly ConstructorInfo DefaultCqrsHandlerRegistrarConstructor =
|
|
||||||
DefaultCqrsHandlerRegistrarType.GetConstructor(
|
|
||||||
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
|
|
||||||
binder: null,
|
|
||||||
[
|
|
||||||
typeof(IIocContainer),
|
|
||||||
typeof(ILogger)
|
|
||||||
],
|
|
||||||
modifiers: null)
|
|
||||||
?? throw new InvalidOperationException(
|
|
||||||
"Failed to locate DefaultCqrsHandlerRegistrar constructor.");
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 为裸测试容器补齐默认 CQRS runtime seam。
|
/// 为裸测试容器补齐默认 CQRS runtime seam。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -92,16 +60,15 @@ public static class CqrsTestRuntime
|
|||||||
|
|
||||||
if (container.Get<ICqrsRuntime>() is null)
|
if (container.Get<ICqrsRuntime>() is null)
|
||||||
{
|
{
|
||||||
var runtimeLogger = LoggerFactoryResolver.Provider.CreateLogger(CqrsDispatcherType.Name);
|
var runtimeLogger = LoggerFactoryResolver.Provider.CreateLogger("CqrsDispatcher");
|
||||||
var runtime = (ICqrsRuntime)CqrsDispatcherConstructor.Invoke([container, runtimeLogger]);
|
var runtime = CqrsRuntimeFactory.CreateRuntime(container, runtimeLogger);
|
||||||
container.Register<ICqrsRuntime>(runtime);
|
container.Register<ICqrsRuntime>(runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container.Get<ICqrsHandlerRegistrar>() is null)
|
if (container.Get<ICqrsHandlerRegistrar>() is null)
|
||||||
{
|
{
|
||||||
var registrarLogger = LoggerFactoryResolver.Provider.CreateLogger(DefaultCqrsHandlerRegistrarType.Name);
|
var registrarLogger = LoggerFactoryResolver.Provider.CreateLogger("DefaultCqrsHandlerRegistrar");
|
||||||
var registrar =
|
var registrar = CqrsRuntimeFactory.CreateHandlerRegistrar(container, registrarLogger);
|
||||||
(ICqrsHandlerRegistrar)DefaultCqrsHandlerRegistrarConstructor.Invoke([container, registrarLogger]);
|
|
||||||
container.Register<ICqrsHandlerRegistrar>(registrar);
|
container.Register<ICqrsHandlerRegistrar>(registrar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\GFramework.Cqrs.Abstractions\GFramework.Cqrs.Abstractions.csproj"/>
|
<ProjectReference Include="..\GFramework.Cqrs.Abstractions\GFramework.Cqrs.Abstractions.csproj"/>
|
||||||
|
<ProjectReference Include="..\GFramework.Cqrs\GFramework.Cqrs.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"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user