Mediatr - 专业化前/后处理器
问题描述:
我目前正在修改我们的asp.net核心应用程序中的一些大型控制器。为此,我们选择了Mediatr,并且我们正在将这些大动作分解为处理器&前/后处理器。Mediatr - 专业化前/后处理器
我们的一些命令需要触发内部通知系统(node.js服务)。为此,我开发了一个后处理器负责通知事件服务。但是,我想仅为从INotify
接口继承的命令“触发”它。换句话说,Mediatr加载所有的前/后处理器,但它只触发那些命令类型与通用约束匹配的处理器。最后它看起来像这样:
public class NotificationPostProcessor<TCommand, TResponse> : IRequestPostProcessor<TCommand, TResponse>
where TCommand : >>INotifyCommand<<
where TResponse : CommandResult
{
(...)
}
如果该命令没有从INotifyCommand继承,那么这个后处理器不会被触发。
预处理器也一样。例如,我需要预处理器为某些特定命令添加一些额外的数据。
目前我所做的是可怕的我相信有更好的办法。
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
包,我不直接注册后&预处理器。
// 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();