C# 如何装饰MediatR处理程序
我只想装饰一个MediatR处理器。我尝试使用行为,但行为为每个实现C# 如何装饰MediatR处理程序,c#,autofac,cqrs,mediatr,C#,Autofac,Cqrs,Mediatr,我只想装饰一个MediatR处理器。我尝试使用行为,但行为为每个实现IRequestHandler 如果您所要做的只是在调用处理程序之前运行一些东西,那么您可以利用行为来实现这一点。我知道您说过您以前尝试过这个,但是,您可以创建一个generate行为来运行IRequestPrecessor的所有实现 注意:下面的过程用于在处理程序运行后实现某些东西,您只需将IRequestPreProcessor的实现更改为IReqiestPostProcessor即可 因此,如果您有命令处理程序: publ
IRequestHandler
如果您所要做的只是在调用处理程序之前运行一些东西,那么您可以利用行为来实现这一点。我知道您说过您以前尝试过这个,但是,您可以创建一个generate行为来运行IRequestPrecessor的所有实现 注意:下面的过程用于在处理程序运行后实现某些东西,您只需将IRequestPreProcessor的实现更改为IReqiestPostProcessor即可 因此,如果您有命令处理程序:
public class ProcessFirstCommandHandler : IRequestHandler<ProcessFirstCommand, bool>
{
public Task<bool> Handle(ProcessFirstCommand request, CancellationToken cancellationToken)
{
Console.WriteLine("Inside Process First Command Handler");
return Task.FromResult(true);
}
}
公共类ProcessFirstCommandHandler:IRequestHandler
{
公共任务句柄(ProcessFirstCommand请求、CancellationToken CancellationToken)
{
WriteLine(“内部进程第一个命令处理程序”);
返回Task.FromResult(true);
}
}
您可以实现IRequestPreProcessor(您所需的装饰器),但一定要指定要针对其运行的命令
public class PreProcessFirstCommand : IRequestPreprocessor<ProcessFirstCommand>
{
public ProcessFirstCommandHandlerDecorator()
{
}
public Task Process(ProcessFirstCommand request, CancellationToken cancellationToken)
{
Console.WriteLine("Inside Process First Command Handler Decorator");
}
}
公共类预处理程序命令:IRequestPreprocessor
{
公共进程FirstCommandHandlerDecorator()
{
}
公共任务进程(ProcessFirstCommand请求、CancellationToken CancellationToken)
{
WriteLine(“内部进程第一个命令处理程序装饰程序”);
}
}
这将由您的泛型预处理行为激活,它将在每个MediatR请求上运行,但只会注入使用泛型类型或指定TRequest类型的IRequestPreProcessor的实现,正如上面的PreProcessFirstCommand类所做的那样:
public class RequestPreProcessValidationBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse>
{
private readonly IEnumerable<IRequestPreProcessor<TRequest>> _preProcessors;
public RequestPreProcessValidationBehaviour(IEnumerable<IRequestPreProcessor<TRequest>> preProcessors)
{
_preProcessors = preProcessors;
}
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
foreach (var processor in _preProcessors)
{
await processor.Process(request, cancellationToken).ConfigureAwait(false);
}
return await next().ConfigureAwait(false);
}
}
public类requestPreprocessValidationBehavior:IPipelineBehavior其中TRequest:IRequest
{
私有只读IEnumerable预处理器;
公共请求预处理验证行为(IEnumerable预处理器)
{
_预处理器=预处理器;
}
公共异步任务句柄(TRequest请求、CancellationToken CancellationToken、RequestHandlerDelegate next)
{
foreach(预处理器中的var处理器)
{
等待处理器。进程(请求、取消令牌)。配置等待(false);
}
返回wait next().configurewait(false);
}
}
注意:此解决方案唯一的一个小问题是,如果您使用ASP.NETCore的默认依赖项注入器,它将只注入实现iRequestReprocessor并指定类型的一个类
例如:
如果您有以下课程:
ProcessFirstCommandHandler.cs
公共类ProcessFirstCommandHandler:IRequestHandler
{
公共任务句柄(ProcessFirstCommand请求、CancellationToken CancellationToken)
{
WriteLine(“我在处理程序中”);
返回Task.FromResult(true);
}
}
预处理firstCommand.cs
公共类预处理程序命令:IRequestPreprocessor
{
公共进程FirstCommandHandlerDecorator()
{
}
公共任务进程(ProcessFirstCommand请求、CancellationToken CancellationToken)
{
WriteLine(“我跑在处理程序前面”);
}
}
另一个preprocessfirstCommand.cs
public类另一个prepreprocessfirst命令:IRequestPreprocessor
{
公共进程FirstCommandHandlerDecorator()
{
}
公共任务进程(ProcessFirstCommand请求、CancellationToken CancellationToken)
{
WriteLine(“我也跑在处理程序前面!”);
}
}
GenericCommand.cs
公共类GenericPreprocessor命令:IRequestPreprocessor
{
公共进程FirstCommandHandlerDecorator()
{
}
公共任务进程(ProcessFirstCommand请求、CancellationToken CancellationToken)
{
WriteLine(“我是泛型的!”);
}
}
另一个GenericPreprocessCommand.cs
public类另一个GenericPreprocessor命令:IRequestPreprocessor
{
公共进程FirstCommandHandlerDecorator()
{
}
公共任务进程(ProcessFirstCommand请求、CancellationToken CancellationToken)
{
WriteLine(“我也是泛型的!”);
}
}
使用前面提到的通用预处理命令,这将同时注入GenericPrepreprocessCommand和另一个GenericPreProcessCommand,但只注入PreProcessFirstCommand或另一个PreProcessFirstCommand中的一个。这似乎只是DI的一个限制。我已经给MediatR的创作者Jimmy Bogard在网站上留下了评论,所以请务必在那里阅读并发表意见
祝你好运 在大多数情况下,使用
iRequestReprocessor
是推荐和首选的方法,但您仍然可以直接调用IoC容器来添加装饰器
例如,使用SimpleInjector:
container.RegisterDecorator(typeof(IRequestHandler<,>), typeof(HandlerDecorator<,>));
container.RegisterDecorator(typeof(IRequestHandler),typeof(handlerdecotor));
对上述问题有何指导?任何人
public class RequestPreProcessValidationBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse>
{
private readonly IEnumerable<IRequestPreProcessor<TRequest>> _preProcessors;
public RequestPreProcessValidationBehaviour(IEnumerable<IRequestPreProcessor<TRequest>> preProcessors)
{
_preProcessors = preProcessors;
}
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
foreach (var processor in _preProcessors)
{
await processor.Process(request, cancellationToken).ConfigureAwait(false);
}
return await next().ConfigureAwait(false);
}
}
public class ProcessFirstCommandHandler : IRequestHandler<ProcessFirstCommand, bool>
{
public Task<bool> Handle(ProcessFirstCommand request, CancellationToken cancellationToken)
{
Console.WriteLine("I'm inside the handler");
return Task.FromResult(true);
}
}
public class PreProcessFirstCommand : IRequestPreprocessor<ProcessFirstCommand>
{
public ProcessFirstCommandHandlerDecorator()
{
}
public Task Process(ProcessFirstCommand request, CancellationToken cancellationToken)
{
Console.WriteLine("I ran before the handler");
}
}
public class AnotherPreProcessFirstCommand : IRequestPreprocessor<ProcessFirstCommand>
{
public ProcessFirstCommandHandlerDecorator()
{
}
public Task Process(ProcessFirstCommand request, CancellationToken cancellationToken)
{
Console.WriteLine("I ran before the handler aswell!");
}
}
public class GenericPreProcessCommand<TRequest> : IRequestPreprocessor<TRequest>
{
public ProcessFirstCommandHandlerDecorator()
{
}
public Task Process(ProcessFirstCommand request, CancellationToken cancellationToken)
{
Console.WriteLine("I'm generic!");
}
}
public class AnotherGenericPreProcessCommand<TRequest> : IRequestPreprocessor<TRequest>
{
public ProcessFirstCommandHandlerDecorator()
{
}
public Task Process(ProcessFirstCommand request, CancellationToken cancellationToken)
{
Console.WriteLine("I'm generic aswell!");
}
}
container.RegisterDecorator(typeof(IRequestHandler<,>), typeof(HandlerDecorator<,>));