Mediatr - Pre/post-processor 专业化
Mediatr - Pre/post-processor specialization
我目前正在改进 asp.net 核心应用程序中的一些大型控制器。为此,我们选择了 Mediatr,目前我们正在将这些大动作拆分为处理程序和 pre/post 处理器。
我们的一些命令需要触发内部通知系统(node.js 服务)。为此,我开发了一个 post 处理器来负责通知事件服务。但是,我想 "trigger" 它 仅用于从 INotify
接口 继承的命令。换句话说,Mediatr 加载所有 pre/post 个处理器,但它只触发那些命令类型与通用约束匹配的处理器。最后它看起来像这样:
public class NotificationPostProcessor<TCommand, TResponse> : IRequestPostProcessor<TCommand, TResponse>
where TCommand : >>INotifyCommand<<
where TResponse : CommandResult
{
(...)
}
如果命令不是从 INotifyCommand 继承,则不会触发此 post-处理器。
预处理器也是如此。例如,我需要我的预处理器向某些特定命令添加一些额外的数据。
目前我所做的很糟糕,我相信还有更好的方法。
public class NotificationPostProcessor<TCommand, TResponse> : IRequestPostProcessor<TCommand, TResponse>
where TCommand : IRequest<TResponse>
where TResponse : CommandResult
{
private readonly INotificationService _service;
public NotificationPostProcessor(INotificationService service)
{
_service = service;
}
public async Task Process(TCommand command, TResponse response)
{
var cmd = command as NotifyBaseCommand;
if (cmd != null && response.IsSuccess)
await _service.Notify(cmd.Event, command, response);
}
}
因为我使用的是默认的 asp.net 核心依赖注入引擎 + MediatR.Extensions.Microsoft.DependencyInjection
包,所以我没有直接注册 Post 和预处理器。
// Pipeline engine used internally to simplify controllers
services.AddMediatR();
// Registers behaviors
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(Pipeline<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(AuditBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPreProcessorBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPostProcessorBehavior<,>));
// Registers command validator
services.AddTransient(typeof(IValidator<RegisterUserCommand>), typeof(RegisterUserCommandValidator));
我必须承认我在这里有点迷路。关于如何改进这个系统有什么想法吗?
谢谢,
塞巴斯蒂安
显然 ASP.net 核心 DI 不支持此功能。
SRC:Support constrained open generic types
它与 Autofac 一起工作。我只需要添加一行代码:)
var host = new WebHostBuilder()
.UseKestrel()
.ConfigureServices(services => services.AddAutofac())
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
我目前正在改进 asp.net 核心应用程序中的一些大型控制器。为此,我们选择了 Mediatr,目前我们正在将这些大动作拆分为处理程序和 pre/post 处理器。
我们的一些命令需要触发内部通知系统(node.js 服务)。为此,我开发了一个 post 处理器来负责通知事件服务。但是,我想 "trigger" 它 仅用于从 INotify
接口 继承的命令。换句话说,Mediatr 加载所有 pre/post 个处理器,但它只触发那些命令类型与通用约束匹配的处理器。最后它看起来像这样:
public class NotificationPostProcessor<TCommand, TResponse> : IRequestPostProcessor<TCommand, TResponse>
where TCommand : >>INotifyCommand<<
where TResponse : CommandResult
{
(...)
}
如果命令不是从 INotifyCommand 继承,则不会触发此 post-处理器。
预处理器也是如此。例如,我需要我的预处理器向某些特定命令添加一些额外的数据。
目前我所做的很糟糕,我相信还有更好的方法。
public class NotificationPostProcessor<TCommand, TResponse> : IRequestPostProcessor<TCommand, TResponse>
where TCommand : IRequest<TResponse>
where TResponse : CommandResult
{
private readonly INotificationService _service;
public NotificationPostProcessor(INotificationService service)
{
_service = service;
}
public async Task Process(TCommand command, TResponse response)
{
var cmd = command as NotifyBaseCommand;
if (cmd != null && response.IsSuccess)
await _service.Notify(cmd.Event, command, response);
}
}
因为我使用的是默认的 asp.net 核心依赖注入引擎 + MediatR.Extensions.Microsoft.DependencyInjection
包,所以我没有直接注册 Post 和预处理器。
// Pipeline engine used internally to simplify controllers
services.AddMediatR();
// Registers behaviors
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(Pipeline<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(AuditBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPreProcessorBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPostProcessorBehavior<,>));
// Registers command validator
services.AddTransient(typeof(IValidator<RegisterUserCommand>), typeof(RegisterUserCommandValidator));
我必须承认我在这里有点迷路。关于如何改进这个系统有什么想法吗?
谢谢, 塞巴斯蒂安
显然 ASP.net 核心 DI 不支持此功能。
SRC:Support constrained open generic types
它与 Autofac 一起工作。我只需要添加一行代码:)
var host = new WebHostBuilder()
.UseKestrel()
.ConfigureServices(services => services.AddAutofac())
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();