[译]MediatR, FluentValidation, and Ninject using Decorators
CQRS
我是CQRS模式的粉丝。对我来说CQRS能让我有更优雅的实现。它同样也有一些缺点:通常需要更多的类,workflow不总是清晰的。
MediatR
MediatR的文档非常不错,在这就不重复了。但是为了有个基本的了解,在这还是举个小例子,来看看command是怎么被处理的:
[Test]
public void ItShouldHandleBasicCommands()
{
var mediator = GetMediator();
var command = new Command();
var response = mediator.Send(command);
response.Should().NotBeNull();
}
MediatR接收一个command,让后将它发送到适当的handler去:
public class Command : IRequest<Response>
{
}
public class CommandHandler : IRequestHandler<Command, Response>
{
public Response Handle(Command message)
{
return new Response();
}
}
注册command和command handler非常简单。下面的例子是关于使用Ninject基于约定来注册。找到所有的handler接口,绑定它们:
kernel.Bind(scan => scan.FromThisAssembly()
.SelectAllClasses()
.Where(o => o.IsAssignableFrom(typeof(IRequestHandler<,>)))
.BindAllInterfaces());
下面是一些其他的注册,它们也非常重要。注册IMediator。factory实例的调用告诉MediatR如何解析单个和多个实例。然后注册MediatR。
kernel.Bind<SingleInstanceFactory>()
.ToMethod(context => (type => context.Kernel.Get(type)));
kernel.Bind<MultiInstanceFactory>()
.ToMethod(context => (type => context.Kernel.GetAll(type)));
var mediator = kernel.Get<IMediator>();
Validation and Decorators
装饰模式可以让我们在不修改对象的前提下,增加这个对象的行为。一个通常的做法是添加输入验证。使用装饰器包装一个command handler,以使得可以在使用前验证这个command。下面的command和command handler简单的返回一个response。
public class Foo : IRequest<Response>
{
public string Message { get; set; }
}
public class FooHandler : IRequestHandler<Foo, Response>
{
public Response Handle(Foo message)
{
return new Response();
}
}
FluentValidation是个非常不错的验证包。首先我们需要一个validation类,然后我们需要用Ninject注册它。
下面是一个简单的验证器。判断Message属性是否为空。如果为空,返回一个错误:
public class FooValidator : AbstractValidator<Foo>
{
public FooValidator()
{
RuleFor(ping => ping.Message).NotEmpty();
}
}
使用Ninject注册验证器非常简单。下面的代码绑定了程序集中所有的验证器:
kernel.Bind(scan => scan.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom(typeof(AbstractValidator<>))
.BindAllInterfaces());
下一步是使用这个validator。下面的代码来自Jimmy Bogard的网站。是一个实现用来在命令发送到handler前验证命令的装饰类的例子:
public class ValidatingHandler<TRequest, TResponse> : IRequestHandler<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
private readonly IRequestHandler<TRequest, TResponse> handler;
private readonly IValidator<TRequest> validator;
public ValidatingHandler(IRequestHandler<TRequest, TResponse> handler, IValidator<TRequest> validator)
{
this.handler = handler;
this.validator = validator;
}
[DebuggerStepThrough]
public TResponse Handle(TRequest message)
{
var validationResult = validator.Validate(message);
if (validationResult.IsValid)
return handler.Handle(message);
throw new ValidationException(validationResult.Errors);
}
}
下一步是如何配置Ninjec来创建一个handler和装饰它。Binding Decorators - Mediators with Ninject这篇文章讲的非常好。"注册handler。当验证handler创建后,注入一个handler。当handler被请求返回一个validating handler。"
当Ninject被要求创建一个handler,它首先创建一个calidating handler。
kernel.Bind(scan => scan.FromThisAssembly()
.SelectAllClasses()
.Where(o => o.IsAssignableFrom(typeof(IRequestHandler<,>)))
.BindAllInterfaces());
kernel.Bind(scan => scan.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom(typeof(IRequestHandler<,>))
.BindAllInterfaces()
.Configure(o => o.WhenInjectedInto(typeof(ValidatingHandler<,>))));
kernel.Bind(typeof(IRequestHandler<,>)).To(typeof(ValidatingHandler<,>));
下面看看如果command的message是空和不是空的时候是什么样子的。
[Test]
public void ItShouldProcessCommands()
{
var mediator = GetMediator();
var command = new Foo { Message = "valid ping" };
var response = mediator.Send(command);
response.Should().NotBeNull();
}
[Test]
public void ItShouldValidateTheCommand()
{
var mediator = GetMediator();
var ping = new Foo();
Action act = () => mediator.Send(ping);
act.ShouldThrow<ValidationException>();
}
本文的源码位于github
[译]MediatR, FluentValidation, and Ninject using Decorators的更多相关文章
- Fluent Validation + NInject3 + MVC5
Fluent Validation + NInject + MVC - Why & How : Part 1 http://fluentvalidation.codeplex.com/ htt ...
- 使用.NET 6开发TodoList应用(11)——使用FluentValidation和MediatR实现接口请求验证
系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 在响应请求处理的过程中,我们经常需要对请求参数的合法性进行校验,如果参数不合法,将不继续进行业务逻辑的处理.我们当然可以将每个 ...
- [译]ASP.NET Core中使用MediatR实现命令和中介者模式
作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9866068.html 在本文中,我将解释命令模式,以及如何利用基于命令模式的第三方库来实现它们,以及如何 ...
- [译]使用mediatR的notification来扩展的的应用
原文 你不希望在controller里面出现任何领域知识 开发者经常有这样的疑问"这个代码应该放在哪呢?"应该使用仓储还是query类?.... 怎么去实现职责分离和单一职责呢? ...
- [译]使用Command模式和MediatR简化你的控制器
原文 你希望保持你的controller足够简单. 你的controller越来越臃肿,你听说command模式是一个给controller瘦身的解决方案. 但是你不知道command模式是否适合你的 ...
- [译]A NON-TRIVIAL EXAMPLE OF MEDIATR USAGE
原文 来看看我目前的一个项目.这个是一个多租户的财务跟踪系统.有一个组织继承的关系.首先得新建一个组织. 表单如下: 这个表单能让用户输入关于组织的一些信息,包括active directory组,一 ...
- 【译】Dependency Injection with Autofac
先说下为什么翻译这篇文章,既定的方向是架构,然后为了学习架构就去学习一些架构模式.设计思想. 突然有一天发现依赖注入这种技能.为了使得架构可测试.易维护.可扩展,需要架构设计为松耦合类型,简单的说也就 ...
- Ninject.Extensions.
最近在使用IoC进行一个较复杂的项目进行架构,在IoC的选择上让我很是纠结.首先我不喜欢大量的配置文件进行配置,那简直是噩梦,比学习一门编程语言还痛苦.我喜欢前一段时间看EF的CodeFirst的那种 ...
- 为什么使用Ninject?
Ninject 3 学习笔记 一.为什么使用Ninject? 分类: 程序2012-11-10 19:23 2209人阅读 评论(0) 收藏 举报 c#iocNinject框架注入 最近在使用IoC进 ...
随机推荐
- [NOI2015]寿司晚宴(状压dp)
为了庆祝NOI的成功开幕,主办方为大家准备了一场寿司晚宴.小G和小W作为参加NOI的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了n−1种不同的寿司,编号1,2,3,⋯,n-1,其中第种 ...
- zabbix添加ceph监控
应用背景: 网上监控ceph集群的资料不算多,git上有个开源的监控项目,是跟zabbix结合的,主要包含一个shell写的脚本和zabbix监控模板,拿来测试小记一下. 开源地址: https:// ...
- BZOJ3566: [SHOI2014]概率充电器 树形+概率dp
3566: [SHOI2014]概率充电器 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1888 Solved: 857[Submit][Stat ...
- 阶乘函数(factorial)——结果在整型范围内的阶乘计算
定义: 在数学中,正整数的阶乘(英语:factorial)是所有小于及等于该数的正整数的积,计为n!,例如5的阶乘计为5!,其值为120: \[ 5!=5\times 4\times 3\times ...
- 源码分析-AutoCloseable
AutoCloseable 该接口用于try-with-resources语法糖提供支持,用于自动关闭资源作用 类型:接口 方法:close(); 详解: close():用于自动关闭资源的时候需要进 ...
- Arcgis for qml - 鼠标拖拽移动
以实现鼠标拖拽文本图层为例 GitHub:ArcGIS拖拽文本 作者:狐狸家的鱼 目的是利用鼠标进行拖拽. 实现两种模式,一种是屏幕上的拖拽,第二种是地图上图层的挪动. 屏幕上的拖拽其实跟ArcGIS ...
- [WC2019] 数树
[WC2019] 数树 Zhang_RQ题解(本篇仅概述) 前言 有进步,只做了半天.... 一道具有极强综合性的数数好题! 强大的多合一题目 精确地数学推导和耐心. 有套路又不失心意. 融合了: 算 ...
- poj2083 Fractal
我一开始的想法是间断性的输出空格和solve(k-1) 但是发现问题很大. 雨菲:可以用一个数组保存啊 我:那不爆了? 雨菲:不会爆. 我一算:729 × 729,还真没爆. 然后就直接WA了.... ...
- 关于数据结构,剑指offer上面的
我很喜欢那些javascript解决的编程题,感觉非常的有意思.我在博客园上面看到了一个同学的博客,他一共发了34篇剑指offer的编程题,还给出了非常详细的解答. 接下来的工作,我做的就是搬运工,不 ...
- java指定编码的按行读写txt文件(几种读写方式的比较)
转: java指定编码的按行读写txt文件(几种读写方式的比较) 2018年10月16日 20:40:02 Handoking 阅读数:976 版权声明:本文为博主原创文章,未经博主允许不得转载. ...