feat(architecture): 集成 Mediator 模式支持

- 添加 Mediator 和 IPublisher 实例的延迟加载功能
- 实现 SendRequestAsync 方法用于发送 Command/Query 请求
- 添加 PublishAsync 方法用于发布通知事件
- 提供 CreateStream 方法支持流式数据处理
- 增加 SendAsync、QueryAsync、PublishEventAsync 等便捷扩展方法
- 更新 SendCommand 和 SendQuery 方法使用完整命名空间
- 在 IArchitectureContext 接口中添加 Mediator 相关方法定义
This commit is contained in:
GeWuYou 2026-02-14 13:49:13 +08:00 committed by gewuyou
parent 9a783f3caa
commit a082b770a9
2 changed files with 205 additions and 4 deletions

View File

@ -5,6 +5,8 @@ using GFramework.Core.Abstractions.model;
using GFramework.Core.Abstractions.query;
using GFramework.Core.Abstractions.system;
using GFramework.Core.Abstractions.utility;
using Mediator;
using ICommand = GFramework.Core.Abstractions.command.ICommand;
namespace GFramework.Core.Abstractions.architecture;
@ -53,7 +55,7 @@ public interface IArchitectureContext
/// <typeparam name="TResult">命令执行结果类型</typeparam>
/// <param name="command">要发送的命令</param>
/// <returns>命令执行结果</returns>
TResult SendCommand<TResult>(ICommand<TResult> command);
TResult SendCommand<TResult>(command.ICommand<TResult> command);
/// <summary>
/// 发送并异步执行一个命令
@ -75,7 +77,7 @@ public interface IArchitectureContext
/// <typeparam name="TResult">查询结果类型</typeparam>
/// <param name="query">要发送的查询</param>
/// <returns>查询结果</returns>
TResult SendQuery<TResult>(IQuery<TResult> query);
TResult SendQuery<TResult>(query.IQuery<TResult> query);
/// <summary>
/// 异步发送一个查询请求
@ -113,6 +115,65 @@ public interface IArchitectureContext
/// <param name="onEvent">要取消注册的事件回调方法</param>
void UnRegisterEvent<TEvent>(Action<TEvent> onEvent);
/// <summary>
/// 发送请求(统一处理 Command/Query
/// </summary>
ValueTask<TResponse> SendRequestAsync<TResponse>(
IRequest<TResponse> request,
CancellationToken cancellationToken = default);
/// <summary>
/// 发送请求(同步版本,不推荐)
/// </summary>
TResponse SendRequest<TResponse>(IRequest<TResponse> request);
/// <summary>
/// 发布通知(一对多事件)
/// </summary>
ValueTask PublishAsync<TNotification>(
TNotification notification,
CancellationToken cancellationToken = default)
where TNotification : INotification;
/// <summary>
/// 创建流式请求(用于大数据集)
/// </summary>
IAsyncEnumerable<TResponse> CreateStream<TResponse>(
IStreamRequest<TResponse> request,
CancellationToken cancellationToken = default);
// === 便捷扩展方法 ===
/// <summary>
/// 发送命令(无返回值)
/// </summary>
ValueTask SendAsync<TCommand>(
TCommand command,
CancellationToken cancellationToken = default)
where TCommand : IRequest<Unit>;
/// <summary>
/// 发送命令(有返回值)
/// </summary>
ValueTask<TResponse> SendAsync<TResponse>(
IRequest<TResponse> command,
CancellationToken cancellationToken = default);
/// <summary>
/// 发送查询
/// </summary>
ValueTask<TResponse> QueryAsync<TResponse>(
IRequest<TResponse> query,
CancellationToken cancellationToken = default);
/// <summary>
/// 发布事件通知
/// </summary>
ValueTask PublishEventAsync<TNotification>(
TNotification notification,
CancellationToken cancellationToken = default)
where TNotification : INotification;
/// <summary>
/// 获取环境对象
/// </summary>

View File

@ -7,6 +7,8 @@ using GFramework.Core.Abstractions.model;
using GFramework.Core.Abstractions.query;
using GFramework.Core.Abstractions.system;
using GFramework.Core.Abstractions.utility;
using Mediator;
using ICommand = GFramework.Core.Abstractions.command.ICommand;
namespace GFramework.Core.architecture;
@ -18,6 +20,18 @@ public class ArchitectureContext(IIocContainer container) : IArchitectureContext
private readonly IIocContainer _container = container ?? throw new ArgumentNullException(nameof(container));
private readonly Dictionary<Type, object> _serviceCache = new();
#region Mediator Integration ()
/// <summary>
/// 获取 Mediator 实例(延迟加载)
/// </summary>
private IMediator? Mediator => GetOrCache<IMediator>();
/// <summary>
/// 获取 IPublisher 实例(用于发布通知)
/// </summary>
private IPublisher? Publisher => GetOrCache<IPublisher>();
/// <summary>
/// 获取指定类型的服务实例,如果缓存中存在则直接返回,否则从容器中获取并缓存
/// </summary>
@ -49,6 +63,132 @@ public class ArchitectureContext(IIocContainer container) : IArchitectureContext
return service;
}
/// <summary>
/// [Mediator] 发送请求Command/Query
/// 这是推荐的新方式,统一处理命令和查询
/// </summary>
/// <typeparam name="TResponse">响应类型</typeparam>
/// <param name="request">请求对象Command 或 Query</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>响应结果</returns>
/// <exception cref="InvalidOperationException">当 Mediator 未注册时抛出</exception>
public async ValueTask<TResponse> SendRequestAsync<TResponse>(
IRequest<TResponse> request,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(request);
var mediator = Mediator;
if (mediator == null)
throw new InvalidOperationException(
"Mediator not registered. Call EnableMediator() in your Architecture.Init() method.");
return await mediator.Send(request, cancellationToken);
}
/// <summary>
/// [Mediator] 发送请求的同步版本(不推荐,仅用于兼容性)
/// </summary>
/// <typeparam name="TResponse">响应类型</typeparam>
/// <param name="request">请求对象</param>
/// <returns>响应结果</returns>
public TResponse SendRequest<TResponse>(IRequest<TResponse> request)
{
return SendRequestAsync(request).AsTask().GetAwaiter().GetResult();
}
/// <summary>
/// [Mediator] 发布通知(一对多)
/// 用于事件驱动场景,多个处理器可以同时处理同一个通知
/// </summary>
/// <typeparam name="TNotification">通知类型</typeparam>
/// <param name="notification">通知对象</param>
/// <param name="cancellationToken">取消令牌</param>
public async ValueTask PublishAsync<TNotification>(
TNotification notification,
CancellationToken cancellationToken = default)
where TNotification : INotification
{
ArgumentNullException.ThrowIfNull(notification);
var publisher = Publisher;
if (publisher == null)
throw new InvalidOperationException("Publisher not registered.");
await publisher.Publish(notification, cancellationToken);
}
/// <summary>
/// [Mediator] 发送请求并返回流(用于大数据集)
/// </summary>
/// <typeparam name="TResponse">响应项类型</typeparam>
/// <param name="request">流式请求</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>异步流</returns>
public IAsyncEnumerable<TResponse> CreateStream<TResponse>(
IStreamRequest<TResponse> request,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(request);
var mediator = Mediator;
if (mediator == null)
throw new InvalidOperationException("Mediator not registered.");
return mediator.CreateStream(request, cancellationToken);
}
#endregion
#region Mediator Extension Methods (便)
/// <summary>
/// [扩展] 发送命令(无返回值)
/// 语法糖,等同于 SendRequestAsync&lt;Unit&gt;
/// </summary>
public async ValueTask SendAsync<TCommand>(
TCommand command,
CancellationToken cancellationToken = default)
where TCommand : IRequest<Unit>
{
await SendRequestAsync(command, cancellationToken);
}
/// <summary>
/// [扩展] 发送命令(有返回值)
/// 语法糖,等同于 SendRequestAsync&lt;TResponse&gt;
/// </summary>
public async ValueTask<TResponse> SendAsync<TResponse>(
IRequest<TResponse> command,
CancellationToken cancellationToken = default)
{
return await SendRequestAsync(command, cancellationToken);
}
/// <summary>
/// [扩展] 发送查询
/// 语法糖,等同于 SendRequestAsync语义更清晰
/// </summary>
public async ValueTask<TResponse> QueryAsync<TResponse>(
IRequest<TResponse> query,
CancellationToken cancellationToken = default)
{
return await SendRequestAsync(query, cancellationToken);
}
/// <summary>
/// [扩展] 发布事件通知
/// 语法糖,等同于 PublishAsync
/// </summary>
public async ValueTask PublishEventAsync<TNotification>(
TNotification notification,
CancellationToken cancellationToken = default)
where TNotification : INotification
{
await PublishAsync(notification, cancellationToken);
}
#endregion
#region Query Execution
@ -58,7 +198,7 @@ public class ArchitectureContext(IIocContainer container) : IArchitectureContext
/// <typeparam name="TResult">查询结果类型</typeparam>
/// <param name="query">要发送的查询</param>
/// <returns>查询结果</returns>
public TResult SendQuery<TResult>(IQuery<TResult> query)
public TResult SendQuery<TResult>(Abstractions.query.IQuery<TResult> query)
{
if (query == null) throw new ArgumentNullException(nameof(query));
var queryBus = GetOrCache<IQueryExecutor>();
@ -135,7 +275,7 @@ public class ArchitectureContext(IIocContainer container) : IArchitectureContext
/// <typeparam name="TResult">命令执行结果类型</typeparam>
/// <param name="command">要发送的命令</param>
/// <returns>命令执行结果</returns>
public TResult SendCommand<TResult>(ICommand<TResult> command)
public TResult SendCommand<TResult>(Abstractions.command.ICommand<TResult> command)
{
ArgumentNullException.ThrowIfNull(command);
var commandBus = GetOrCache<ICommandExecutor>();