NET Core中使用MediatR实现命令和中介者模式

https://www.cnblogs.com/yilezhu/p/9866068.html

在本文中,我将解释命令模式,以及如何利用基于命令模式的第三方库来实现它们,以及如何在ASP.NET Core中使用它来解决我们的问题并使代码简洁。因此,我们将通过下面的主题来进行相关的讲解。

什么是命令模式?

命令模式的简单实例以及中介者模式的简单描述

MVC中的瘦控制器是什么?我们是如何实现使控制器变瘦的?

我们如何在我们的.NET Core应用程序中使用MediatR

使用命令和事件的实例

命令模式及其简单实例

从根本上讲,命令模式是一种数据驱动的设计模式,属于行为模式的范畴。命令是我们可以执行的某种操作或行为,它可以是活动的一部分。一个活动可以有一个或多个命令和实现。

我们可以这样来说,请求以命令的形式包裹在对象中,并传给调用对象。调用者(代理)对象查找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令 。

一个简单的例子是多种类型的消息。Message类包含SendEmail()和SendSms()等属性和方法。使用两种类型的命令,并且需要一个接口,它应该由实现了EmailMessageCommand和SMSMessageCommand的类类继承。还使用代理类来调用特定类型的消息类来处理操作。

Mediatr

Main class

class Program

{

static void Main(string[] args)

{

Message message = new Message();

message.CustomMessage = "Welcome by Email";

EmailMessageCommand emailMessageCommand = new EmailMessageCommand(message);

        Message message2 = new Message();
message2.CustomMessage = "Welcome by SMS";
SmsMessageCommand smsMessageCommand = new SmsMessageCommand(message2); Broker broker = new Broker();
broker.SendMessage(emailMessageCommand);
broker.SendMessage(smsMessageCommand);
Console.ReadKey(); }
}

消息类

public class Message

{

public string CustomMessage { get; set; }

    public void EmailMessage()
{
Console.WriteLine($"{CustomMessage} : Email Message sent");
} public void SmsMessage()
{
Console.WriteLine($"{CustomMessage} : Sms Message sent");
}
}

接口和代理类

public interface IMessageCommand

{

void DoAction();

}

public class Broker

{

public void SendMessage(IMessageCommand command)

{

command.DoAction();

}

}

命令

public class EmailMessageCommand : IMessageCommand

{

private Message oMessage;

    public EmailMessageCommand(Message oMessage)
{
this.oMessage = oMessage;
} public void DoAction()
{
oMessage.EmailMessage();
}
} public class SmsMessageCommand : IMessageCommand
{
private Message oMessage; public SmsMessageCommand(Message oMessage)
{
this.oMessage = oMessage;
}
public void DoAction()
{ oMessage.SmsMessage();
}
}

输出

Command, Mediator Pattern In ASP.NET Core Using Mediatr

什么是瘦控制器,我们为什么需要它?什么是MediatR?

当我们开始使用MVC框架进行开发时,逻辑是用控制器的动作方法编写的;就像我们有一个简单的电子商务应用程序,其中用户应该会下订单。我们有一个控制器,OrderController,用来管理订单。当用户下订单时,我们应该在数据库中保存记录。

在此之前,我们有一个简化的代码。然而,经过一段时间后,我们意识到还有一个确认电子邮件的业务需求。现在,第二步是发送确认电子邮件给客户。后来,我们意识到,在这个步骤之后,我们还需要执行另一个操作,即,记录信息等。最后,我们还需要将用户的信息保存到CRM中。关键是它会增长控制器的大小。现在,我们可以称之为“臃肿控制器”。

基于命令的体系结构允许我们发送命令来执行某些操作,并且我们有单独的命令处理程序,使关注点分离和提高单一职责。为了实现这个架构,我们可以使用第三方库,比如MediatR(Mediator.),它为我们做了很多基础工作。中介模式定义了一个对象,该对象封装了一组对象是如何交互的。

中介模式的优势及MediatR如何帮助我们实现中介模式

中介模式定义了一个对象,该对象封装了一组对象是如何交互的(如维基百科定义的)。

它通过保持对象彼此明确地相互引用来促进松散耦合。

它通过允许通信被卸载到一个只处理这类的类来促进单一责任原则。

MediatR库如何帮助我们

MediatR允许我们通过让控制器Action向处理程序发送请求消息来将控制器与业务逻辑解耦。MediatR库支持两种类型的操作。

命令(预期输出结果)

事件(请求者不关心接下来发生了什么,不期待结果)

我们已经介绍了命令模式,因此是时候定义一些命令并使用MediatR发出命令了。

在ASP.NET Core中安装

我们需要从NuGet安装MediatR和MediatR.Extensions.Microsoft.DependencyInjection包。

使用Mediatr在ASP.NETæ ¸å¿ƒä¸­çš„å‘½ä"¤ï¼Œä"‹ä½“模式

使用Mediatr在ASP.NETæ ¸å¿ƒä¸­çš„å‘½ä"¤ï¼Œä"‹ä½“模式

当这两个软件包安装完毕后,我们需要添加services.AddMediatR(); 到startup.cs文件。看起来像这样。

使用Mediatr在ASP.NETæ ¸å¿ƒä¸­çš„å‘½ä"¤ï¼Œä"‹ä½“模式

现在,我们可以使用.NET Core 项目中的MediatR了。

实例

第一个示例演示了使用MediatR使用请求/响应类型的操作。它期望对请求做出一些反应。

第二个示例将向您展示一个事件,其中多个处理程序执行它们的工作,调用者并不关心接下来会发生什么,也不期望任何结果/响应。

第一个例子

在这种场景下,我们希望注册用户并期望对请求做出一些响应。如果响应返回true,我们可以像登录用户一样进行进一步的操作。

首先,我们需要创建一个继承自IRequest的类。

public class NewUser: IRequest

{

public string Username { get; set; }

public string Password { get; set; }

}

IRequest是指请求的响应是布尔响应。

现在,需要一个处理程序来处理这种类型的请求。

public class NewUserHandler : IRequestHandler<NewUser, bool>

{

public Task Handle(NewUser request, CancellationToken cancellationToken)

{

// save to database

return Task.FromResult(true);

}

}

现在我们有了命令和它的处理程序,我们可以调用MediatR在我们的控制器中做一些操作。

这些是Home控制器的动作方法。

public class HomeController : Controller

{

private readonly IMediator _mediator;

    public HomeController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet]
public ActionResult Register()
{
return View();
} [HttpPost]
public ActionResult Register(NewUser user)
{
bool result = _mediator.Send(user).Result; if (result)
return RedirectToAction("Login"); return View();
}
}

第一个例子的结论

注册操作方法使用了[HttpPost]属性进行修饰,并接受新的用户注册请求。然后,它请求MediatR 进行处理。它期望来自请求的结果/响应,如果结果是真的,则将用户重定向到登录页面。

这里,我们有简洁的代码,大部分的工作是在控制器外部完成的。这实现了对不同操作的处理的关注点分离(SoC)和单一责任的分离。

在第二个示例中,我们将演示使用多个处理程序对命令执行不同操作的场景。

第二个实例

在这种情况下,我们使NewUser 继承了INotification

public class NewUser : INotification

{

public string Username { get; set; }

public string Password { get; set; }

}

现在,有三个处理程序逐个执行,以完成他们的工作。这些都是从INotificationHandler继承下来的。

public class NewUserHandler : INotificationHandler

{

public Task Handle(NewUser notification, CancellationToken cancellationToken)

{

//Save to log

Debug.WriteLine(" **** Save user in database *****");

return Task.FromResult(true);

}

}

第二个处理程序在下面的代码中定义。

public class EmailHandler : INotificationHandler

{

public Task Handle(NewUser notification, CancellationToken cancellationToken)

{

//Send email

Debug.WriteLine(" **** Email sent to user *****");

return Task.FromResult(true);

}

}

这是第三个处理程序的代码

public class LogHandler : INotificationHandler

{

public Task Handle(NewUser notification, CancellationToken cancellationToken)

{

//Save to log

Debug.WriteLine(" **** User save to log *****");

return Task.FromResult(true);

}

}

然后,我们控制器中的代码像下面这样

public class AccountsController : Controller

{

private readonly IMediator _mediator;

public AccountsController(IMediator mediator)

{

_mediator = mediator;

}

[HttpGet]

public ActionResult Login()

{

return View();

}

[HttpGet]

public ActionResult Register()

{

return View();

}

    [HttpPost]
public ActionResult Register(NewUser user)
{
_mediator.Publish(user);
return RedirectToAction("Login");
}
}

第二个例子的结论

此应用程序的输出如下:

当用户注册后,三个处理程序逐个执行——分别是NewUserHandler、EmailHandler和LogHandler,并执行它们的操作。

这里,我们使用了Publish 方法,而不是Send 函数。发布将调用订阅了NewUser 类的所有处理程序。这只是一个示例,我们可以根据命令进行思考,然后按照我们在命令模式中讨论的方式相应地执行一些操作。

Mediatr是如何提供帮助的?

它可以用来隐藏实现的细节,用来使控制器代码更加干净和可维护,可以重用多个处理程序,并且每个处理程序都有自己的责任,因此易于管理和维护。

在我的下一篇文章中,我将尝试解释CQRS架构模式及其优点以及如何使用MediatR来实现CQRS。

原文地址:https://www.c-sharpcorner.com/article/command-mediator-pattern-in-asp-net-core-using-mediatr2/

NET Core中使用MediatR实现命令和中介者模式的更多相关文章

  1. [译]ASP.NET Core中使用MediatR实现命令和中介者模式

    作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9866068.html 在本文中,我将解释命令模式,以及如何利用基于命令模式的第三方库来实现它们,以及如何 ...

  2. 【翻译】asp.net core中使用MediatR

    这篇文章来自:https://ardalis.com/using-mediatr-in-aspnet-core-apps 本文作为翻译,有一些单词翻译成中文可能会有一些误解(对于读者)或者错误(对于作 ...

  3. Entity Framework Core中的数据迁移命令

    使用程序包管理控制台输入命令. 数据迁移命令: Add-Migration  对比当前数据库和模型的差异,生成相应的代码,使数据库和模型匹配的. Remove-Migration 删除上次的迁移 Sc ...

  4. .net core系列之《.net core中使用MySql以及Dapper》

    当我们决定使用.Net Core开发的时候,就放弃使用SqlServer的打算吧.那应该选择哪个数据库呢?一般选择MySql的比较多. 接下来我们来演示在.Net Core中使用MySQL吧. 1.原 ...

  5. 在 ASP.NET Core 项目中使用 MediatR 实现中介者模式

    一.前言  最近有在看 DDD 的相关资料以及微软的 eShopOnContainers 这个项目中基于 DDD 的架构设计,在 Ordering 这个示例服务中,可以看到各层之间的代码调用与我们之前 ...

  6. 一起来学习.net core程序使用中介者模式:MediatR插件

    中介者模式是一种常见的设计模式,旨再降低程序的耦合性,因为传统的三层模式层层之间需要显示的调用,必须上层依赖下层,耦合性很高,为了解耦,将所有的指令单独放在一个位置处理,其他位置均通过这个位置来间接的 ...

  7. ASP.NET Core 中文文档 第二章 指南(5) 在 Nano Server 上运行ASP.NET Core

    原文 ASP.NET Core on Nano Server 作者 Sourabh Shirhatti 翻译 娄宇(Lyrics) 校对 刘怡(AlexLEWIS).许登洋(Seay).谢炀(kile ...

  8. ASP.NET Core 中文文档 第三章 原理(12)托管

    原文:Hosting 作者:Steve Smith 翻译:娄宇(Lyrics) 校对:何镇汐.许登洋(Seay) 为了运行 ASP.NET Core 应用程序,你需要使用 WebHostBuilder ...

  9. 在ASP.NET Core中使用Angular2,以及与Angular2的Token base身份认证

    注:下载本文提到的完整代码示例请访问:How to authorization Angular 2 app with asp.net core web api 在ASP.NET Core中使用Angu ...

随机推荐

  1. 从Redux源码探索最佳实践

    前言 Redux 已经历了几个年头,很多 React 技术栈开发者选用它,我也是其中一员.期间看过数次源码,从最开始为了弄清楚某一部分运行方式来解决一些 Bug,到后来看源码解答我的一些假设性疑问,到 ...

  2. sql统计上周销售量的起止时间

    开始日期: >select DATEADD(Day, 1 - DATEPART(Weekday,CONVERT(varchar(10), GETDATE() - 7, 120)), CONVER ...

  3. redis_入门网址

    redis中文网: http://www.redis.cn/ 可以 试用 以及 下载 redis百度百科:http://baike.baidu.com/link?url=MEkE5MpGAOfJ7ci ...

  4. Jenkins自动打包配置

    当时也是花费了不少时间来配置Jenkins自动打包的问题,觉得还是需要记录一下. 1.安装Jenkins,这个很简单,不需要多说. 2.下载Git Plugin,Gradle Plugin,Andro ...

  5. AtCoder Regular Contest 098

    AtCoder Regular Contest 098 C - Attention 题意 给定一个只包含"E","W"字符串,可以花一的花费使他们互相转换.选定 ...

  6. jsp——js事件修改属性样式的两种方法(直接赋值、修改属性)、验证表单符合某要求、阻止表单提交、告诉浏览器不要缓存

    代码 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncodi ...

  7. cmake手册

    cmake手册 部分转载自:http://www.cnblogs.com/coderfenghc/tag/cmake/ CMake2.8.3 主索引 命令名称 用法 描述 命令选项 生成器 命令 属性 ...

  8. crm开发(基于ssh)(五)

    1 信息查询 (1)多条件组合查询 -拼接hql语句 -使用离线对象 2 添加数据字典表 (1)改造添加客户功能 3 统计分析 (1)调用普通sql实现 (2)结果处理操作 4 使用ssh注解整合 ( ...

  9. python作业大纲分析

    2018-11-22 目前自学python这么久,零零散散的写了几次作业,下面是几个在完成过程中遇到困难较多的作业. 1.ATM+购物车系统 需求: 1.额度 15000或自定义  2.实现购物商城, ...

  10. 通过实例深入理解HTML5/CSS3/SVG/WebGL的技术本质

    常常听到人们对于HTML5的讨论,看了页面头部这个那个就是Html5,误认为HTML5只是新增些标签“而已”,学完了W3School似乎就理解了.实际上很多从业人员并没有深入理解业界为什么要推出HTM ...