Mediatr - 处理前/后处理器专业化

时间:2017-07-19 08:53:56

标签: generics dependency-injection asp.net-core mediatr

我正在改进我们的asp.net核心应用程序中的一些大型控制器。为此,我们选择了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包,我不会直接注册Post&amp;预处理器。

   // 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));

我必须承认我在这里有点失落。关于如何改进这个系统的任何想法?

谢谢你, 的Sebastien

1 个答案:

答案 0 :(得分:0)

显然ASP.net核心DI不支持此功能。

SRC:Support constrained open generic types

Autofac合作。我只需要添加一行代码:)

Started PATCH "/lessons/4" for 127.0.0.1 at 2017-07-20 11:23:27 +0900
Processing by LessonsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"+95AUkvSbAUfVzAp9xweeiuq8IKq3gdqJB5oP8HoRP3NvkoYHkGRYe1TQSMxVtTZGPlATx6ltb0SThD6ifMXpg==", "lesson"=>{"title"=>"まずはじめに", "content"=>"Jelly beans chupa chups soufflé toffee cookie croissant sugar plum cookie. Danish caramels gummi bears marzipan apple pie cupcake jelly pudding dragée. Jelly-o pastry halvah sweet. Pudding jujubes marshmallow pie soufflé. Tart chocolate bar dragée bonbon cotton candy jelly beans chupa chups. Cheesecake tart chupa chups candy canes sweet roll biscuit candy lollipop. Chupa chups lemon drops chocolate bear claw muffin tiramisu pastry marzipan ice cream. Sweet candy canes danish halvah caramels cupcake donut lemon drops gummi bears."}, "commit"=>"更新", "id"=>"4"}
  Lesson Load (0.1ms)  SELECT  "lessons".* FROM "lessons" WHERE "lessons"."id" = ? LIMIT ?  [["id", 4], ["LIMIT", 1]]
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 1], ["LIMIT", 1]]
No template found for LessonsController#update, rendering head :no_content
Completed 204 No Content in 112ms (ActiveRecord: 0.3ms)