feat(cqrs): 添加CQRS运行时模块和兼容性扩展

- 新增ContextAwareMediatorCommandExtensions提供命令扩展方法的兼容性别名
- 新增ContextAwareMediatorExtensions提供CQRS统一接口扩展方法的兼容性别名
- 新增ContextAwareMediatorQueryExtensions提供查询扩展方法的兼容性别名
- 添加CqrsRuntimeModule用于注册CQRS运行时和处理器注册器到依赖注入容器
- 更新IArchitectureContext接口添加新版CQRS请求、命令、查询和通知的统一入口
- 添加架构上下文的CQRS处理器注册相关单元测试
- 配置项目文件以支持多目标框架和包引用管理
This commit is contained in:
GeWuYou 2026-04-15 19:42:08 +08:00
parent f7b4ae9995
commit a80ff59631
29 changed files with 129 additions and 86 deletions

View File

@ -15,7 +15,7 @@ namespace GFramework.Core.Abstractions.Architectures;
/// </summary>
/// <remarks>
/// <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>
/// </remarks>
public interface IArchitectureContext
@ -175,7 +175,7 @@ public interface IArchitectureContext
/// <param name="query">要发送的 CQRS 查询。</param>
/// <returns>查询结果。</returns>
/// <remarks>
/// 这是迁移后的推荐查询入口。新查询应优先实现 <c>GFramework.Core.Abstractions.Cqrs.Query.IQuery&lt;TResponse&gt;</c>。
/// 这是迁移后的推荐查询入口。新查询应优先实现 <c>GFramework.Cqrs.Abstractions.Cqrs.Query.IQuery&lt;TResponse&gt;</c>。
/// </remarks>
TResponse SendQuery<TResponse>(GFramework.Cqrs.Abstractions.Cqrs.Query.IQuery<TResponse> query);

View File

@ -1,8 +1,8 @@
using System.Reflection;
using GFramework.Core.Abstractions.Cqrs;
using GFramework.Core.Abstractions.Logging;
using GFramework.Core.Architectures;
using GFramework.Core.Logging;
using GFramework.Cqrs;
using GFramework.Cqrs.Abstractions.Cqrs;
namespace GFramework.Core.Tests.Architectures;

View File

@ -1,6 +1,7 @@
using System.ComponentModel;
using GFramework.Core.Abstractions.Rule;
using GFramework.Cqrs.Abstractions.Cqrs.Command;
using GFramework.Cqrs.Extensions;
namespace GFramework.Core.Extensions;

View File

@ -1,6 +1,7 @@
using System.ComponentModel;
using GFramework.Core.Abstractions.Rule;
using GFramework.Cqrs.Abstractions.Cqrs;
using GFramework.Cqrs.Extensions;
namespace GFramework.Core.Extensions;

View File

@ -1,6 +1,7 @@
using System.ComponentModel;
using GFramework.Core.Abstractions.Rule;
using GFramework.Cqrs.Abstractions.Cqrs.Query;
using GFramework.Cqrs.Extensions;
namespace GFramework.Core.Extensions;

View File

@ -10,6 +10,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\GFramework.Cqrs.Abstractions\GFramework.Cqrs.Abstractions.csproj"/>
<ProjectReference Include="..\GFramework.Cqrs\GFramework.Cqrs.csproj"/>
<ProjectReference Include="..\$(AssemblyName).Abstractions\$(AssemblyName).Abstractions.csproj"/>
</ItemGroup>
<ItemGroup>

View File

@ -1,8 +1,8 @@
using GFramework.Core.Abstractions.Architectures;
using GFramework.Core.Abstractions.Cqrs;
using GFramework.Core.Abstractions.Ioc;
using GFramework.Core.Cqrs.Internal;
using GFramework.Core.Logging;
using GFramework.Cqrs;
using GFramework.Cqrs.Abstractions.Cqrs;
namespace GFramework.Core.Services.Modules;
@ -37,11 +37,12 @@ public sealed class CqrsRuntimeModule : IServiceModule
{
ArgumentNullException.ThrowIfNull(container);
var dispatcherLogger = LoggerFactoryResolver.Provider.CreateLogger(nameof(CqrsDispatcher));
var registrarLogger = LoggerFactoryResolver.Provider.CreateLogger(nameof(DefaultCqrsHandlerRegistrar));
var dispatcherLogger = LoggerFactoryResolver.Provider.CreateLogger("CqrsDispatcher");
var registrarLogger = LoggerFactoryResolver.Provider.CreateLogger("DefaultCqrsHandlerRegistrar");
container.Register<ICqrsRuntime>(new CqrsDispatcher(container, dispatcherLogger));
container.Register<ICqrsHandlerRegistrar>(new DefaultCqrsHandlerRegistrar(container, registrarLogger));
container.Register<ICqrsRuntime>(CqrsRuntimeFactory.CreateRuntime(container, dispatcherLogger));
container.Register<ICqrsHandlerRegistrar>(
CqrsRuntimeFactory.CreateHandlerRegistrar(container, registrarLogger));
}
/// <summary>

View File

@ -1,4 +1,3 @@
using GFramework.Core.Abstractions.Cqrs;
using GFramework.Core.Abstractions.Logging;
using GFramework.Core.Architectures;
using GFramework.Core.Ioc;

View File

@ -13,7 +13,7 @@
using GFramework.Cqrs.Abstractions.Cqrs.Command;
namespace GFramework.Core.Cqrs.Command;
namespace GFramework.Cqrs.Command;
/// <summary>
/// 表示一个基础命令类,用于处理带有输入和响应的命令模式实现。

View File

@ -1,4 +1,4 @@
namespace GFramework.Core.Abstractions.Cqrs;
namespace GFramework.Cqrs;
/// <summary>
/// 声明程序集内可供运行时直接调用的 CQRS 处理器注册器类型。

View 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);
}
}

View File

@ -1,7 +1,7 @@
using GFramework.Core.Abstractions.Rule;
using GFramework.Cqrs.Abstractions.Cqrs.Command;
namespace GFramework.Core.Extensions;
namespace GFramework.Cqrs.Extensions;
/// <summary>
/// 提供对 <see cref="IContextAware" /> 接口的 CQRS 命令扩展方法。

View File

@ -1,7 +1,7 @@
using GFramework.Core.Abstractions.Rule;
using GFramework.Cqrs.Abstractions.Cqrs;
namespace GFramework.Core.Extensions;
namespace GFramework.Cqrs.Extensions;
/// <summary>
/// 提供对 <see cref="IContextAware" /> 接口的 CQRS 统一扩展方法。

View File

@ -1,7 +1,7 @@
using GFramework.Core.Abstractions.Rule;
using GFramework.Cqrs.Abstractions.Cqrs.Query;
namespace GFramework.Core.Extensions;
namespace GFramework.Cqrs.Extensions;
/// <summary>
/// 提供对 <see cref="IContextAware" /> 接口的 CQRS 查询扩展方法。

View File

@ -11,6 +11,7 @@
<ItemGroup>
<ProjectReference Include="..\GFramework.Cqrs.Abstractions\GFramework.Cqrs.Abstractions.csproj"/>
<ProjectReference Include="..\GFramework.Core.Abstractions\GFramework.Core.Abstractions.csproj"/>
</ItemGroup>
</Project>

View 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;

View File

@ -1,6 +1,6 @@
using GFramework.Core.Abstractions.Logging;
namespace GFramework.Core.Abstractions.Cqrs;
namespace GFramework.Cqrs;
/// <summary>
/// 定义由源码生成器产出的 CQRS 处理器注册器契约。

View File

@ -7,7 +7,7 @@ using GFramework.Core.Abstractions.Logging;
using GFramework.Core.Abstractions.Rule;
using GFramework.Cqrs.Abstractions.Cqrs;
namespace GFramework.Core.Cqrs.Internal;
namespace GFramework.Cqrs.Internal;
/// <summary>
/// GFramework 自有 CQRS 运行时分发器。

View File

@ -1,10 +1,9 @@
using System.Reflection;
using GFramework.Core.Abstractions.Cqrs;
using GFramework.Core.Abstractions.Ioc;
using GFramework.Core.Abstractions.Logging;
using GFramework.Cqrs.Abstractions.Cqrs;
namespace GFramework.Core.Cqrs.Internal;
namespace GFramework.Cqrs.Internal;
/// <summary>
/// 在架构初始化期间扫描并注册 CQRS 处理器。

View File

@ -3,7 +3,7 @@ using GFramework.Core.Abstractions.Ioc;
using GFramework.Core.Abstractions.Logging;
using GFramework.Cqrs.Abstractions.Cqrs;
namespace GFramework.Core.Cqrs.Internal;
namespace GFramework.Cqrs.Internal;
/// <summary>
/// 默认的 CQRS 处理器注册器实现。

View File

@ -14,7 +14,7 @@
using GFramework.Cqrs.Abstractions.Cqrs;
using GFramework.Cqrs.Abstractions.Cqrs.Notification;
namespace GFramework.Core.Cqrs.Notification;
namespace GFramework.Cqrs.Notification;
/// <summary>
/// 表示一个基础通知类,用于处理带有输入的通知模式实现。

View File

@ -13,7 +13,7 @@
using GFramework.Cqrs.Abstractions.Cqrs.Query;
namespace GFramework.Core.Cqrs.Query;
namespace GFramework.Cqrs.Query;
/// <summary>
/// 表示一个基础查询类,用于处理带有输入和响应的查询模式实现。

View File

@ -14,7 +14,7 @@
using GFramework.Cqrs.Abstractions.Cqrs;
using GFramework.Cqrs.Abstractions.Cqrs.Request;
namespace GFramework.Core.Cqrs.Request;
namespace GFramework.Cqrs.Request;
/// <summary>
/// 表示一个基础请求类,用于处理带有输入和响应的请求模式实现。

View File

@ -1,10 +1,10 @@
using GFramework.Core.Abstractions.Rule;
using GFramework.Core.Coroutine;
using GFramework.Core.Coroutine.Extensions;
using GFramework.Core.Extensions;
using GFramework.Cqrs.Abstractions.Cqrs;
using GFramework.Cqrs.Abstractions.Cqrs.Command;
using GFramework.Cqrs.Abstractions.Cqrs.Query;
using GFramework.Cqrs.Extensions;
namespace GFramework.Godot.Coroutine;

View File

@ -15,6 +15,11 @@ public static class PathContests
/// </summary>
public const string CoreNamespace = $"{BaseNamespace}.Core";
/// <summary>
/// GFramework CQRS runtime 命名空间
/// </summary>
public const string CqrsNamespace = $"{BaseNamespace}.Cqrs";
/// <summary>
/// GFramework Godot模块命名空间
/// </summary>
@ -45,4 +50,9 @@ public static class PathContests
/// GFramework核心抽象层命名空间
/// </summary>
public const string CoreAbstractionsNamespace = $"{CoreNamespace}.Abstractions";
}
/// <summary>
/// GFramework CQRS 抽象层命名空间
/// </summary>
public const string CqrsAbstractionsNamespace = $"{CqrsNamespace}.Abstractions";
}

View File

@ -38,7 +38,7 @@ public class CqrsHandlerRegistryGeneratorTests
}
}
namespace GFramework.Core.Abstractions.Cqrs
namespace GFramework.Cqrs.Abstractions.Cqrs
{
public interface IRequest<TResponse> { }
public interface INotification { }
@ -47,7 +47,10 @@ public class CqrsHandlerRegistryGeneratorTests
public interface IRequestHandler<in TRequest, TResponse> where TRequest : IRequest<TResponse> { }
public interface INotificationHandler<in TNotification> where TNotification : INotification { }
public interface IStreamRequestHandler<in TRequest, out TResponse> where TRequest : IStreamRequest<TResponse> { }
}
namespace GFramework.Cqrs
{
public interface ICqrsHandlerRegistry
{
void Register(Microsoft.Extensions.DependencyInjection.IServiceCollection services, GFramework.Core.Abstractions.Logging.ILogger logger);
@ -62,7 +65,7 @@ public class CqrsHandlerRegistryGeneratorTests
namespace TestApp
{
using GFramework.Core.Abstractions.Cqrs;
using GFramework.Cqrs.Abstractions.Cqrs;
public sealed record PingQuery() : IRequest<string>;
public sealed record DomainEvent() : INotification;
@ -78,11 +81,11 @@ public class CqrsHandlerRegistryGeneratorTests
// <auto-generated />
#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;
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)
{
@ -93,19 +96,19 @@ public class CqrsHandlerRegistryGeneratorTests
global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient(
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));
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(
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));
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(
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));
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 INotification { }
@ -152,7 +155,10 @@ public class CqrsHandlerRegistryGeneratorTests
public interface IRequestHandler<in TRequest, TResponse> where TRequest : IRequest<TResponse> { }
public interface INotificationHandler<in TNotification> where TNotification : INotification { }
public interface IStreamRequestHandler<in TRequest, out TResponse> where TRequest : IStreamRequest<TResponse> { }
}
namespace GFramework.Cqrs
{
public interface ICqrsHandlerRegistry
{
void Register(Microsoft.Extensions.DependencyInjection.IServiceCollection services, GFramework.Core.Abstractions.Logging.ILogger logger);
@ -167,7 +173,7 @@ public class CqrsHandlerRegistryGeneratorTests
namespace TestApp
{
using GFramework.Core.Abstractions.Cqrs;
using GFramework.Cqrs.Abstractions.Cqrs;
public sealed record VisibleRequest() : IRequest<string>;

View File

@ -8,13 +8,17 @@ namespace GFramework.SourceGenerators.Cqrs;
[Generator]
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 IRequestHandlerMetadataName = $"{CqrsNamespace}.IRequestHandler`2";
private const string INotificationHandlerMetadataName = $"{CqrsNamespace}.INotificationHandler`1";
private const string IStreamRequestHandlerMetadataName = $"{CqrsNamespace}.IStreamRequestHandler`2";
private const string ICqrsHandlerRegistryMetadataName = $"{CqrsNamespace}.ICqrsHandlerRegistry";
private const string CqrsHandlerRegistryAttributeMetadataName = $"{CqrsNamespace}.CqrsHandlerRegistryAttribute";
private const string IRequestHandlerMetadataName = $"{CqrsContractsNamespace}.IRequestHandler`2";
private const string INotificationHandlerMetadataName = $"{CqrsContractsNamespace}.INotificationHandler`1";
private const string IStreamRequestHandlerMetadataName = $"{CqrsContractsNamespace}.IStreamRequestHandler`2";
private const string ICqrsHandlerRegistryMetadataName = $"{CqrsRuntimeNamespace}.ICqrsHandlerRegistry";
private const string CqrsHandlerRegistryAttributeMetadataName =
$"{CqrsRuntimeNamespace}.CqrsHandlerRegistryAttribute";
private const string ILoggerMetadataName = $"{LoggingNamespace}.ILogger";
private const string IServiceCollectionMetadataName = "Microsoft.Extensions.DependencyInjection.IServiceCollection";
private const string GeneratedNamespace = "GFramework.Generated.Cqrs";
@ -273,7 +277,7 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
builder.AppendLine("#nullable enable");
builder.AppendLine();
builder.Append("[assembly: global::");
builder.Append(CqrsNamespace);
builder.Append(CqrsRuntimeNamespace);
builder.Append(".CqrsHandlerRegistryAttribute(typeof(global::");
builder.Append(GeneratedNamespace);
builder.Append('.');
@ -287,7 +291,7 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
builder.Append("internal sealed class ");
builder.Append(GeneratedTypeName);
builder.Append(" : global::");
builder.Append(CqrsNamespace);
builder.Append(CqrsRuntimeNamespace);
builder.AppendLine(".ICqrsHandlerRegistry");
builder.AppendLine("{");
builder.Append(

View File

@ -4,10 +4,11 @@ using System.Reflection;
using GFramework.Core.Abstractions.Cqrs;
using GFramework.Core.Abstractions.Ioc;
using GFramework.Core.Abstractions.Logging;
using GFramework.Core.Architectures;
using GFramework.Core.Ioc;
using GFramework.Core.Logging;
using GFramework.Cqrs;
using GFramework.Cqrs.Abstractions.Cqrs;
using GFramework.Cqrs.Command;
namespace GFramework.Tests.Common;
@ -20,7 +21,9 @@ namespace GFramework.Tests.Common;
/// </remarks>
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(
"GFramework.Core.Cqrs.Internal.CqrsHandlerRegistrar",
throwOnError: true)!;
@ -40,41 +43,6 @@ public static class CqrsTestRuntime
?? throw new InvalidOperationException(
"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>
/// 为裸测试容器补齐默认 CQRS runtime seam。
/// </summary>
@ -92,16 +60,15 @@ public static class CqrsTestRuntime
if (container.Get<ICqrsRuntime>() is null)
{
var runtimeLogger = LoggerFactoryResolver.Provider.CreateLogger(CqrsDispatcherType.Name);
var runtime = (ICqrsRuntime)CqrsDispatcherConstructor.Invoke([container, runtimeLogger]);
var runtimeLogger = LoggerFactoryResolver.Provider.CreateLogger("CqrsDispatcher");
var runtime = CqrsRuntimeFactory.CreateRuntime(container, runtimeLogger);
container.Register<ICqrsRuntime>(runtime);
}
if (container.Get<ICqrsHandlerRegistrar>() is null)
{
var registrarLogger = LoggerFactoryResolver.Provider.CreateLogger(DefaultCqrsHandlerRegistrarType.Name);
var registrar =
(ICqrsHandlerRegistrar)DefaultCqrsHandlerRegistrarConstructor.Invoke([container, registrarLogger]);
var registrarLogger = LoggerFactoryResolver.Provider.CreateLogger("DefaultCqrsHandlerRegistrar");
var registrar = CqrsRuntimeFactory.CreateHandlerRegistrar(container, registrarLogger);
container.Register<ICqrsHandlerRegistrar>(registrar);
}
}

View File

@ -10,6 +10,7 @@
<ItemGroup>
<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\GFramework.Core.csproj"/>
</ItemGroup>