命令查询责任分离(CQRS)是一种体系结构模式,它将命令(更改数据)与查询(读取数据)分开。有关更多详细信息和对学习资料的参考,请参阅“关于cqrs标记”。不要与命令查询隔离([CQS])混淆,后者是CQRS所包含的对象方法设计原则。
我可以在CQRS中的另一个CommandHandler中调用QueryHandler/CommandHandler吗
我正在开发一个 ASP.NET Core 6.0 Web API 项目。我使用 CQRS 设计模式。 我想更新航空公司表(代码优先 EF Core)。所以首先我需要找到航空公司的ID。 我有
对于每个条件,cqrs 中应该有单个还是多个命令?示例:如果有命令GenerateAndSendReportToClient,它可以通过SSN或TaxNumber找到客户,是否应该有
如何使用 MediatR 和 FluentValidation 实现通用 ValidationBehavion,以便 ValidationBehavion 仅在命令上触发
我正在使用 CQRS 并为了分隔命令和查询而创建了自定义接口,因此我希望我的 ValidationBehavion 仅在继承 IRequest 的自定义 ICommand 上触发 我正在使用 CQRS 并分离命令和查询,我创建了自定义接口,因此我希望我的 ValidationBehavion 仅在继承 IRequest 的自定义 ICommand 上触发,而不是在所有 IRequest 请求上触发。 为了分离命令和查询,我创建了自定义界面: (作为响应值,我使用 ErrorOr 库。但我认为不值得研究它,只需记住命令和查询总是有响应) public interface ICommand<TResponse> : IRequest<ErrorOr<TResponse>> { } public interface IQuery<TResponse> : IRequest<ErrorOr<TResponse>> { } public interface ICommandHandler<TCommand, TResponse> : IRequestHandler<TCommand, ErrorOr<TResponse>> where TCommand : ICommand<TResponse> { } public interface IQueryHandler<TQuery, TResponse> : IRequestHandler<TQuery, ErrorOr<TResponse>> where TQuery : IQuery<TResponse> { } 我知道一种标准方法,其中 IPipelineBehavior 会向任何请求者触发,然后我们检查该请求者是否有验证器: public class ValidationBehavion<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse> where TResponse : IErrorOr { private readonly IValidator<TRequest>? _validator; public ValidationBehavion(IValidator<TRequest>? validator = null) { _validator = validator; } public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken) { if(_validator is null) { return await next(); } var validationResult = await _validator.ValidateAsync(request); if (validationResult.IsValid) { return await next(); } var validationErrors = validationResult.Errors .ConvertAll(error => Errors.Wands.NotValid( error.PropertyName, error.ErrorMessage)); return (dynamic)validationErrors; } } 由于命令和查询是分离的,我想我可以指定 ICommand 而不是 IRequest 并重做 ValidationBehavion,如下所示: public class ValidationBehavion<TRequest, TResponse> : IPipelineBehavior<TRequest, ErrorOr<TResponse>> where TRequest : ICommand<TResponse> { private readonly IValidator<TRequest> _validator; public ValidationBehavion(IValidator<TRequest> validator) { _validator = validator; } public async Task<ErrorOr<TResponse>> Handle(TRequest request, RequestHandlerDelegate<ErrorOr<TResponse>> next, CancellationToken cancellationToken) { var validationResult = await _validator.ValidateAsync(request); if (validationResult.IsValid) { return await next(); } var validationErrors = validationResult.Errors .ConvertAll(error => Errors.Wands.NotValid( error.PropertyName, error.ErrorMessage)); return validationErrors; } } 但是这个 IPipelineBehavior 根本不起作用,我不知道为什么。 您可能需要注册该行为。你的startup.cs应该看起来像这样: public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddMediatR(typeof(Startup)); services.AddValidatorsFromAssemblyContaining<Startup>(); // Register pipeline behaviors services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>)); services.AddTransient(typeof(IPipelineBehavior<,>), typeof(AuthorizationBehavior<,>)); services.AddTransient(typeof(IPipelineBehavior<,>), typeof(PerformanceBehavior<,>)); services.AddTransient(typeof(IPipelineBehavior<,>), typeof(UnhandledExceptionBehavior<,>)); // Register request pre-processors and post-processors services.AddTransient(typeof(IRequestPreProcessor<>), typeof(ValidationPreProcessor<>)); services.AddTransient(typeof(IRequestPostProcessor<,>), typeof(LoggingPostProcessor<,>)); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } 您在这里有完整的教程:https://argosco.io/using-ipipelinebehavior-irequestpreprocessor-and-irequestpostprocessor-in-a-net-core-api/net/
我正在开发一个事件源应用程序,该应用程序可以抓取来自不同博彩公司的体育博彩游戏。我的系统中有两个主要聚合: 游戏:代表体育博彩赛事...
我一直在尝试找出使用 NestJS CQRS 配方(https://docs.nestjs.com/recipes/cqrs)时进行“事件溯源”的首选方式。 我一直在看 NestJS fra...
Nestjs 中如何处理事件持久化?文档(阅读 CQRS 配方)中并不清楚我们应该如何保存事件以及如何使用快照回复它们。也不清楚如何
在DDD(领域驱动设计)中,存储库方法可以接受组成聚合的实体或值对象吗?
据我所知,每个聚合根都有自己的存储库,并且存储库应该仅与聚合实体及其主键一起使用。 例如,对于聚合预约: 公共...
连接到 AxonServer 节点失败:不可用:网络因未知原因关闭
尝试使用 docker 镜像连接到 axon 服务器时: 版本:'3' 服务: 轴突服务器: 图片:axoniq/axonserver:2024.1.2-jdk-17-nonroot 主机名:axonserver 容器_na...
需要帮助 我正在使用 CQRS 实现我想知道在消息传递方面我应该选择哪种方法保证哪种方法适合 CQRS 如果我至少选择一个,我会...
我使用Kafka Streams来处理用户数据的变化以及与用户操作相对应的事件。 我使用连接操作 (KStream-KTable) 丰富事件,然后将丰富的事件写入 Elastic...
从一个 BoundedContext/AggregateRoot 获取数据并从另一个 BoundedContext/AggregateRoot 获取一些附加数据的推荐方法?
我正在考虑使用 Spring Modulith 构建模块化整体,并应用领域驱动设计(DDD)。 我有一个关于从多个模块获取数据的问题以及建议是什么......
注入IRequestHandler时出现错误 System.AggregateException:'某些服务无法构建(验证服务描述符时出错'ServiceType:MediatR.IRequestHan...
c# XUnit Fluent Assertions:为 BadRequest 编写单元测试用例
我正在开发具有 CQRS 中介模式的 ASP.NET Core 8 Web API,目前正在为所有控制器创建 XUnit 测试。一切正常,希望我无法为 BadRe 创建测试...
我正在开发具有 CQRS 中介模式的 ASP.NET Core 8 Web API,目前正在为所有控制器创建测试。一切正常,希望我无法为 BadRequest 创建测试
在研究领域事件和集成事件时,我发现一些文章倾向于将异步领域事件称为集成事件。 我对领域事件的理解是......
使用事件溯源时如何保持一致性?我们使用事件源来处理平衡,因此我们不会将当前状态存储在数据库中。我有以下场景: 假设我有
在CQRS和领域驱动设计方法结合使用的场景中,是否允许以贫血的方式实现“查询端模型”? 在我看来: 领域驱动设计
我有一个通知子域,其中所有电子邮件和短信通知都是根据系统其他部分的集成事件从系统处理/发送的。 每个用例都会创建一个
我正在构建自己的 CQRS 库,我似乎无法理解为什么某个字段没有正确设置。更具体地说,这个问题似乎存在于扩展我的课程中
我有一个事件源 AxonFramework 应用程序,它需要(在某些事件发生时/之后)调用外部服务。这些调用需要来自预测的数据,事件已更新/pro...