Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use MediatR to implement POST requests

2025-01-30 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces the relevant knowledge of "how to use MediatR to implement POST request". In the actual case operation process, many people will encounter such difficulties. Next, let Xiaobian lead you to learn how to handle these situations! I hope you can read carefully and learn something!

demand

The requirements are simple: how to create new TodoLists and TodoItems and persist them.

Beginners to implement according to the tutorial, it should be divided into the following steps: create Controller and implement POST method; practical incoming request parameter new a database entity object; call IRepository to complete the database write, at most will add a layer of Service in the middle. This practice itself is not a problem, but also the only way to master the development skills from the beginner stage, which helps to understand the process of logic call.

For slightly formal projects, the customary implementation of. NET engineering is to effectively classify and manage business logic and eliminate redundant code by using some mature class library frameworks to achieve the purpose of clear and concise business logic responsibilities. The two libraries we use most often at this stage are AutoMapper and MediatR.

Target

Properly organize and use MediatR to complete POST requests.

Principles and Ideas

First, let's briefly introduce this class library.

About CQRS, Mediator and MediatR

CQRS mode

The full name of CQRS mode is "Command Query Responsibility Segregation". As the literal meaning, the purpose of CQRS mode is to distinguish the accusation of read operation from write operation and use different models to represent it. From CRUD's point of view, it is to treat R and CUD separately. As shown below:

这个模式可以有效地应用到具有主从分离的数据库架构中,当需要获取数据时,从只读数据库(一般是从库)中读取数据,当需要写入或更新数据时,向主库进行操作。

CQRS模式旨在解决的问题是:为了屏蔽数据库层面"写优先"还是"读优先"的优化设计策略,在业务逻辑侧进行解耦。

任何设计模式都是对解决特定问题的一个Trade off,自然也带来了一些缺点,首先就是服务内部的组件复杂度上升了,因为需要创建额外的类来实现CQRS模式;其次如果数据层是分离的,那么可能会有数据的状态不一致问题。

中介者Mediator模式

这是23种基本设计模式中的一个,属于行为型设计模式,它给出了组件之间交互的一种解耦的方式。简单参考下图,具体内容就不过多解释了,任何一篇介绍设计模式的文章都有介绍。

这种设计模式实际上是一种采用依赖倒置(Inversion of Control, IoC)的方式,实现了图中蓝色组件的松耦合。

MediatR

这是在开发中被广泛采用的实现以上两种设计模式的类库,更准确的说法是,它通过应用中介者模式,实现了进程内CQRS。基本思想是所有来自API接口和数据存储之间的逻辑,都需要通过MediatR来组织(即所谓的"中介者")。

从实现上看,MediatR提供了几组用于不同场景的接口,我们在本文中处理的比较多的是IRequest/IRequestHandler以及INotification/INotificationHander两组接口,更多的请参考官方文档和例子。

实现

所有需要使用MediatR的地方都集中在Application项目中。

引入MediatR$ dotnet add src/TodoList.Application/TodoList.Application.csproj package MediatR.Extensions.Microsoft.DependencyInjection

为了适配CQRS的模式,我们在Application项目中的TodoLists和TodoItems下相同地创建几个文件夹:

Commands:用于组织CUD相关的业务逻辑;

Queries:用于组织R相关的业务逻辑;

EventHandlers:用于组织领域事件处理的相关业务逻辑。

在Application根目录下同样创建DependencyInjection.cs用于该项目的依赖注入:

DependencyInjection.cs

using System.Reflection;using Microsoft.Extensions.DependencyInjection;namespace TodoList.Application;public static class DependencyInjection{ public static IServiceCollection AddApplication(this IServiceCollection services) { services.AddMediatR(Assembly.GetExecutingAssembly()); return services; }}

并在Api项目中使用:

// 省略其他...// 添加应用层配置builder.Services.AddApplication();// 添加基础设施配置builder.Services.AddInfrastructure(builder.Configuration);实现Post请求

在本章中我们只实现TodoList和TodoItem的Create接口(POST),剩下的接口后面的文章中逐步涉及。

POST TodoList

在Application/TodoLists/Commands/下新建一个目录CreateTodoList用于存放创建一个TodoList相关的所有逻辑:

CreateTodoListCommand.cs

using MediatR;using TodoList.Application.Common.Interfaces;namespace TodoList.Application.TodoLists.Commands.CreateTodoList;public class CreateTodoListCommand : IRequest{ public string? Title { get; set; }}public class CreateTodoListCommandHandler : IRequestHandler{ private readonly IRepository _repository; public CreateTodoListCommandHandler(IRepository repository) { _repository = repository; } public async Task Handle(CreateTodoListCommand request, CancellationToken cancellationToken) { var entity = new Domain.Entities.TodoList { Title = request.Title }; await _repository.AddAsync(entity, cancellationToken); return entity.Id; }}

有一些实践是将Request和RequestHandler分开两个文件,我更倾向于像这样将他俩放在一起,一是保持简洁,二是当你需要顺着一个Command去寻找它对应的Handler时,不需要更多的跳转。

接下来在TodoListController里实现对应的POST方法,

using MediatR;using Microsoft.AspNetCore.Mvc;using TodoList.Application.TodoLists.Commands.CreateTodoList;namespace TodoList.Api.Controllers;[ApiController][Route("/todo-list")]public class TodoListController : ControllerBase{ private readonly IMediator _mediator; // 注入MediatR public TodoListController(IMediator mediator) => _mediator = mediator; [HttpPost] public async Task Create([FromBody] CreateTodoListCommand command) { var createdTodoList = await _mediator.Send(command); // 出于演示的目的,这里只返回创建出来的TodoList的Id, // 实际使用中可能会选择IActionResult作为返回的类型并返回CreatedAtRoute对象, // 因为我们还没有去写GET方法,返回CreatedAtRoute会报错(找不到对应的Route),等讲完GET后会在那里更新 return createdTodoList.Id; }}

POST TodoItem

类似TodoListController和CreateTodoListCommand的实现,这里我直接把代码贴出来了。

CreateTodoItemCommand.cs

using MediatR;using TodoList.Application.Common.Interfaces;using TodoList.Domain.Entities;using TodoList.Domain.Events;namespace TodoList.Application.TodoItems.Commands.CreateTodoItem;public class CreateTodoItemCommand : IRequest{ public Guid ListId { get; set; } public string? Title { get; set; }}public class CreateTodoItemCommandHandler : IRequestHandler{ private readonly IRepository _repository; public CreateTodoItemCommandHandler(IRepository repository) { _repository = repository; } public async Task Handle(CreateTodoItemCommand request, CancellationToken cancellationToken) { var entity = new TodoItem { // 这个ListId在前文中的代码里漏掉了,需要添加到Domain.Entities.TodoItem实体上 ListId = request.ListId, Title = request.Title, Done = false }; await _repository.AddAsync(entity, cancellationToken); return entity.Id; }}

TodoItemController.cs

using MediatR;using Microsoft.AspNetCore.Mvc;using TodoList.Application.TodoItems.Commands.CreateTodoItem;namespace TodoList.Api.Controllers;[ApiController][Route("/todo-item")]public class TodoItemController : ControllerBase{ private readonly IMediator _mediator; // 注入MediatR public TodoItemController(IMediator mediator) => _mediator = mediator; [HttpPost] public async Task Create([FromBody] CreateTodoItemCommand command) { var createdTodoItem = await _mediator.Send(command); // 处于演示的目的,这里只返回创建出来的TodoItem的Id,理由同前 return createdTodoItem.Id; }}验证

运行Api项目,通过Hoppscotch发送对应接口请求:

创建TodoList验证

请求

return

database

The first piece of data is seed data, and the second piece is what we just created.

Create TodoItem Validation

Continue to take the Id of the TodoList you just created to create a new TodoItem:

request

return

database

The last one is our new creation, the rest is seed data.

"How to use MediatR to implement POST request" content is introduced here, thank you for reading. If you want to know more about industry-related knowledge, you can pay attention to the website. Xiaobian will output more high-quality practical articles for everyone!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report