首页 > 作文

.NET 6开发TodoList应用之使用MediatR实现POST请求

更新时间:2023-04-04 12:24:46 阅读: 评论:0

需求

需求很简单:如何创建新的todolisttodoitem并持久化。

初学者按照教程去实现的话,应该分成以下几步:创建controller并实现post方法;实用传入的请求参数new一个数据库实体对象;调用irepository<t>完成数据库的写入,最多会在中间加一层rvice。这个做法本身没有问题,也是需要从初学阶段开始扎实地掌握开发技能的必经之路,有助于帮助理解逻辑调用的过程。

对于稍微正式一些的项目,.net工程上习惯的实现是通过使用一些比较成熟的类库框架,有效地对业务逻辑进行分类管理、消除冗余代码,以达到业务逻辑职责清晰简洁的目的。在这个阶段我们经常使用的两个类库分别是automapper和mediatr,本文结合post请求,先介绍关于mediatr部分,下一篇关于get请求,会涉及automapper的部分。

目标

合理组织并使用mediatr,完成post请求。

原理与思路

首先来简单地介绍一下这个类库。

关于cqrs模式、中介者模式和mediatr

cqrs模式

cqrs模式全称是“command query responsibility gregation”,正如字面意思,cqrs模式的目的在于将读取操作和写入操作的指责区分开,并使用不同的model去表示。从crud的角度来说,就是把rcud区分开来对待。如下图所示:

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

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

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

中介者mediator模式

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

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

mediatr

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

从实现上看,mediatr提供了几组用于不同场景的接口,我们在本文中处理的比较多的是irequest<t>/irequesthandler<t>以及inotification<t>/inotificationhander<t>两组接口,更多的请参考官方文档和例子。

实现

所有需要使用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 irvicecollection addapplication(this irvicecollection rvices)    {        rvices.addmediatr(asmbly.getexecutingasmbly());        return rvices;    }}

并在api项目中使用:

// 省略其他...// 添加应用层配置builder.rvices.addapplication();// 添加基础设施配置builder.rvices.addinfrastructure(builder.configuration);

实现post请求

在本章中我们只实现todolisttodoitem的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<guid>{    public string? title { get; t; }}public class createtodolistcommandhandler : irequesthandler<createtodolistcommand, guid>{    private readonly irepository<domain.entities.todolist> _repository;    public createtodolistcommandhandler(irepository<domain.entities.todolist> repository)    {        _repository = repository;    }    public async task<guid> handle(createtodolistcommand request, cancellationtoken cancellationtoken)    {        var entity = new domain.entities.todolist        {            title = request.title        };       小学生心理健康与辅导 await _repository.addasync(entity, cancellationtoken);        return entity.id;    }}

有一些实践是将requestrequ旅游宣传esthandler分开两个文件,我更倾向于像这样将他俩放在一起,一是保持简洁,二是当你需要顺着一个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 : controllerba{    private readonly imediator _mediator;    // 注入mediatr    public todolistcontroller(imediator mediator)        => _mediator = mediator;    [httppost]    public async task<guid> create([frombody] createtodolistcommand command)    {        var createdtodolist = await _mediator.nd(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<guid&我的姐姐电影简介gt;{    public guid listid { get; t; }    public string? title { get; t; }}public class createtodoitemcommandhandler : irequesthandler<createtodoitemcommand, guid>{    private readonly irepository<todoitem> _repository;    public createtodoitemcommandhandler(irepository<todoitem> repository)    {        _repository = repository;    }    public async task<guid> handle(createtodoitemcommand request, cancellationtoken cancellationtoken)    {        var entity = new todoitem        {            // 这个listid在前文中的代码里漏掉了,需要添加到domain.entities.todoitem实体上            listid = request.listid,            title = request.title,            done = fal        };        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 : controllerba{    private readonly imediator _mediator;    // 注入mediatr    public todoitemcontroller(imediator mediator)         => _mediator = mediator;    [httppost]    public async task<guid> create([frombody] createtodoitemcommand command)    {        var createdtodoitem = await _mediator.nd(command);        // 处于演示的目的,这里只返回创建出来的todoitem的id,理由同前        return createdtodoitem.id;    }}

验证

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

创建todolist验证

请求

返回

数据库

第一条数据是种子数据,第二条是我们刚才创建的。

创建todoitem验证

继续拿刚才创建的这个todolist的id来创建新的todoitem:

请求

返回

数据库

最后一条是我们新创建的,其余是种子数据。

总结

我们已经通过演示在post请求中实现mediatr库带来的cqrs模式,在这篇文章里我留了一个坑。就是领域事件的handler并没有任何演示,只是创建了一个文件夹,结合在这篇文章中留下来的发布领域事件的坑,会在delete的文章中填完。

看起来使用cqrs模式使得我们的代码结构变得更加复杂了,但是对于一些再复杂一些的实际项目中,正确使用cqrs模式有助于你分析和整理业务需求,并将相关的业务需求以及相关模型梳理到统一的位置进行管理,包括在后续的文章里我们会陆续向其中加入诸如入参校验、出参类型转换等逻辑。认真思考并运用习惯之后,大家可以自行体会这样做的“权衡”。

参考资料

mediatr

mediator

以上就是.net 6开发todolist应用之使用medi的笔画顺序iatr实现post请求的详细内容,更多关于.net 6 mediatr实现post请求的资料请关注www.887551.com其它相关文章!

本文发布于:2023-04-04 12:24:45,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/136b4d9c9699152c11316b2e34d2d3d5.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:.NET 6开发TodoList应用之使用MediatR实现POST请求.doc

本文 PDF 下载地址:.NET 6开发TodoList应用之使用MediatR实现POST请求.pdf

标签:模式   逻辑   目的   业务
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图