一.介绍

简单了解下开源项目 MedatR, eShopOnContainers, MediatR作者Jimmy Bogard :

Simple mediator implementation in .NET
In-process messaging with no dependencies.
Supports request/response, commands, queries, notifications and events, synchronous and async with intelligent dispatching via C# generic variance.
.NET中的简单中介实现 进程内没有依赖关系消息传递。支持以同步或异步的形式进行请求/响应,命令,查询,通知和事件的消息传递,并通过C#泛型支持消息的智能调度。

MediatR实现Pipeline ,通过Autofac 注入Log,FluentValidation ,来实现管道里记录日志,管道里验证实体数据.

二.MediatR的使用

1.安装NuGet包:

Install-Package MediatR.Extensions.Microsoft.DependencyInjectionFixed
Install-Package Autofac.Extensions.DependencyInjection

2.修改Startup.cs文件

public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
var container = new ContainerBuilder();
container.Populate(services);
container.RegisterModule(new MediatorModule());
return new AutofacServiceProvider(container.Build());
}

3.添加MediatorModule.cs文件

添加 builder.RegisterGeneric(typeof(xxx<,>)).As(typeof(IPipelineBehavior<,>)); 按你添加的顺序执行管道

public class MediatorModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly)
.AsImplementedInterfaces(); // Register all the Command classes (they implement IRequestHandler) in assembly holding the Commands
builder.RegisterAssemblyTypes(typeof(CreateOrderCommand).GetTypeInfo().Assembly)
.AsClosedTypesOf(typeof(IRequestHandler<,>));
// Register the DomainEventHandler classes (they implement INotificationHandler<>) in assembly holding the Domain Events
// builder.RegisterAssemblyTypes(typeof(ValuesController.Pings).GetTypeInfo().Assembly)
// .AsClosedTypesOf(typeof(INotificationHandler<>)); // Register the Command's Validators (Validators based on FluentValidation library)
builder
.RegisterAssemblyTypes(typeof(CreateOrderCommandValidator).GetTypeInfo().Assembly)
.Where(t => t.IsClosedTypeOf(typeof(IValidator<>)))
.AsImplementedInterfaces(); builder.Register<ServiceFactory>(context =>
{
var componentContext = context.Resolve<IComponentContext>();
return t => { object o; return componentContext.TryResolve(t, out o) ? o : null; };
}); builder.RegisterGeneric(typeof(LoggingBehavior<,>)).As(typeof(IPipelineBehavior<,>));
builder.RegisterGeneric(typeof(ValidatorBehavior<,>)).As(typeof(IPipelineBehavior<,>));
// builder.RegisterGeneric(typeof(TransactionBehaviour<,>)).As(typeof(IPipelineBehavior<,>)); }
}

 4.添加LoggingBehavior.cs文件

public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
private readonly ILogger<LoggingBehavior<TRequest, TResponse>> _logger;
public LoggingBehavior(ILogger<LoggingBehavior<TRequest, TResponse>> logger) => _logger = logger; public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
_logger.LogInformation("----- Handling command {CommandName} ({@Command})", request.GetGenericTypeName(), request);
var response = await next();
_logger.LogInformation("----- Command {CommandName} handled - response: {@Response}", request.GetGenericTypeName(), response); return response;
}
}

 5.添加ValidatorBehavior.cs文件

public class ValidatorBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
private readonly ILogger<ValidatorBehavior<TRequest, TResponse>> _logger;
private readonly IValidator<TRequest>[] _validators; public ValidatorBehavior(IValidator<TRequest>[] validators, ILogger<ValidatorBehavior<TRequest, TResponse>> logger)
{
_validators = validators;
_logger = logger;
} public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
var typeName = request.GetGenericTypeName(); _logger.LogInformation("----- Validating command {CommandType}", typeName); var failures = _validators
.Select(v => v.Validate(request))
.SelectMany(result => result.Errors)
.Where(error => error != null)
.ToList(); if (failures.Any())
{
_logger.LogWarning("Validation errors - {CommandType} - Command: {@Command} - Errors: {@ValidationErrors}", typeName, request, failures); throw new OrderingDomainException(
$"Command Validation Errors for type {typeof(TRequest).Name}", new ValidationException("Validation exception", failures));
} return await next();
}
}

6.添加CreateOrderCommandValidator.cs

public class CreateOrderCommandValidator : AbstractValidator<CreateOrderCommand>
{
public CreateOrderCommandValidator()
{
RuleFor(command => command.City).NotEmpty();
RuleFor(command => command.Street).NotEmpty();
RuleFor(command => command.State).NotEmpty();
RuleFor(command => command.Country).NotEmpty();
RuleFor(command => command.ZipCode).NotEmpty();
RuleFor(command => command.CardNumber).NotEmpty().Length(, );
RuleFor(command => command.CardHolderName).NotEmpty();
RuleFor(command => command.CardExpiration).NotEmpty().Must(BeValidExpirationDate).WithMessage("Please specify a valid card expiration date");
RuleFor(command => command.CardSecurityNumber).NotEmpty().Length();
RuleFor(command => command.CardTypeId).NotEmpty();
RuleFor(command => command.OrderItems).Must(ContainOrderItems).WithMessage("No order items found");
} private bool BeValidExpirationDate(DateTime dateTime)
{
return dateTime >= DateTime.UtcNow;
} private bool ContainOrderItems(IEnumerable<CreateOrderCommand.OrderItemDTO> orderItems)
{
return orderItems.Any();
}
}

初学者浅度剖析eShopOnContainers 里面用到的MediatR .的更多相关文章

  1. 初学者应该怎么学习前端?web前端的发展路线大剖析!

    写在最前: 优秀的Web前端开发工程师要在知识体系上既要有广度和深度!应该具备快速学习能力. 前端开发工程师不仅要掌握基本的Web前端开发技术,网站性能优化.SEO和服务器端的基础知识,而且要学会运用 ...

  2. Apache Spark源码剖析

    Apache Spark源码剖析(全面系统介绍Spark源码,提供分析源码的实用技巧和合理的阅读顺序,充分了解Spark的设计思想和运行机理) 许鹏 著   ISBN 978-7-121-25420- ...

  3. [.NET领域驱动设计实战系列]专题十:DDD扩展内容:全面剖析CQRS模式实现

    一.引言 前面介绍的所有专题都是基于经典的领域驱动实现的,然而,领域驱动除了经典的实现外,还可以基于CQRS模式来进行实现.本专题将全面剖析如何基于CQRS模式(Command Query Respo ...

  4. SpringMVC源码剖析(一)- 从抽象和接口说起

    SpringMVC作为Struts2之后异军突起的一个表现层框架,正越来越流行,相信javaee的开发者们就算没使用过SpringMVC,也应该对其略有耳闻.我试图通过对SpringMVC的设计思想和 ...

  5. Unity协程(Coroutine)原理深入剖析

    Unity协程(Coroutine)原理深入剖析 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 其实协程并没有那么复杂,网上很多地方都说是多 ...

  6. Node初学者入门,一本全面的NodeJS教程(转载)

    分类 JS学习   发布 ourjs  2013-12-02 注意 转载须保留原文链接,译文链接,作者译者等信息.     作者: Manuel Kiessling  翻译: goddyzhao &a ...

  7. Unity协程(Coroutine)原理深入剖析(转载)

    记得去年6月份刚开始实习的时候,当时要我写网络层的结构,用到了协程,当时有点懵,完全不知道Unity协程的执行机制是怎么样的,只是知道函数的返回值是IEnumerator类型,函数中使用yield r ...

  8. .NET平台技术体系梳理+初学者学习路径推荐+我们的愿景与目标

    文章出自:http://www.cnblogs.com/ice-river/p/3475041.html 一 .NET平台技术体系梳理 .NET平台应用领域众多(桌面开发,web开发,移动开发),不断 ...

  9. Spring 事务管理高级应用难点剖析--转

    第 1 部分 http://www.ibm.com/search/csass/search/?q=%E4%BA%8B%E5%8A%A1&sn=dw&lang=zh&cc=CN& ...

随机推荐

  1. November 23rd 2016 Week 48th Wednesday

    I always like walking in the rain, so no one can see me crying. 我一直喜欢在雨中行走,那样就没人能看到我的眼泪. I like walk ...

  2. November 8th 2016 Week 46th Tuesday

    When he can't, he tries a new way to share a new pair. 当他做不到时,他尝试一种新的方式:分享. To share, your failing e ...

  3. windows下python 正确安装词云包wordcloud的方法

    安装wordcloud的时候果然还是出现了问题,试了网上说的好多办法,最后找到了一种成功率高的,可以优先尝试一下 下载.whl文件http://www.lfd.uci.edu/~gohlke/pyth ...

  4. Django之Model (ORM)

    传统操作数据库 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层 ...

  5. IPython学习笔记(二)-魔术命令

    .魔术命令:以%为前缀的命令,是ipython的特殊命令,方便完成常见的任务.,常见的魔术命令有:%run,%paste,%cpaste,%timeit,%reset,%hist,%debug,%bo ...

  6. ZooKeeper(二)Java API使用

    ZooKeeper官网提供了Java和C的API. 本文使用Java API来实现ZooKeeper的基本操作. 前言 下图中的Replicated Database是包含完整数据树(entire d ...

  7. iPhone将NSString转换编码集为gb2312或者gbk的方法

    很多时候软件读取的中文网页编码集是gb2312,所以显示出来的是乱码.这时需要将NSString文字编码转换.你可以试试以下代码 NSURL *url = [NSURL URLWithString:u ...

  8. java 解析http user-agent 信息

    解析http user-agent信息,使用uasparser-0.6.1.jar和jregex-1.2_01.jar两个包 import cz.mallat.uasparser.OnlineUpda ...

  9. L2-025 分而治之(图)

    (这不会是我最后一天写算法题的博客吧...有点感伤...) 题目: 分而治之,各个击破是兵家常用的策略之一.在战争中,我们希望首先攻下敌方的部分城市,使其剩余的城市变成孤立无援,然后再分头各个击破.为 ...

  10. Mac编译安装swfTools

    Mac编译安装swfTools Mac编译安装swfTools 下载源码 解压源码 安装依赖项 ./configure执行配置或者执行如下配置命令: 需要注意这里存在部分代码错误,需要修改解决后执行 ...