1

我目前正在修改我们的 asp.net 核心应用程序中的一些大型控制器。为此,我们选择了 Mediatr,我们目前正在将这些大动作拆分为处理程序和前/后处理器。

我们的一些命令需要触发内部通知系统(node.js 服务)。为此,我开发了一个负责通知事件服务的后处理器。但是,我只想为从interface继承的命令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 & Pre 处理器。

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

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

谢谢你,塞巴斯蒂安

4

1 回答 1

0

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

SRC:支持受限的开放泛型类型

它与Autofac一起使用。我只需要添加一行代码:)

    var host = new WebHostBuilder()
        .UseKestrel()
        .ConfigureServices(services => services.AddAutofac())
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIISIntegration()
        .UseStartup<Startup>()
        .UseApplicationInsights()
        .Build();
于 2017-07-20T02:30:42.550 回答