【发布时间】:2020-02-24 22:17:32
【问题描述】:
我在我的 .Net Core 项目中使用 Mediatr,我想知道 Mediatr 中的处理程序是单例的还是每个发送请求的新实例;我知道 Mediatr 是单例的,但对于它用于命令或查询的处理程序,我不太确定。
我倾向于认为他们也是单身人士;但只是想再次确认。
【问题讨论】:
我在我的 .Net Core 项目中使用 Mediatr,我想知道 Mediatr 中的处理程序是单例的还是每个发送请求的新实例;我知道 Mediatr 是单例的,但对于它用于命令或查询的处理程序,我不太确定。
我倾向于认为他们也是单身人士;但只是想再次确认。
【问题讨论】:
事实上,所有这些东西的生命周期都是有据可查的 https://github.com/jbogard/MediatR.Extensions.Microsoft.DependencyInjection/blob/master/README.md
仅供参考:IMediator 是瞬态的(不是单例),IRequestHandler 具体实现是瞬态的,依此类推,实际上它在任何地方都是瞬态的。
但请注意,将 Scoped 服务与 Mediatr 处理程序一起使用,它的工作方式与预期不同,更像是单例,除非您手动创建范围。
【讨论】:
对于handlers,按照源码看后,好像都被添加为Transient了。
services.AddTransient(@interface, type);
对于 IMediator 本身,它看起来默认是生命周期:
services.Add(new ServiceDescriptor(typeof(IMediator), serviceConfiguration.MediatorImplementationType, serviceConfiguration.Lifetime));
请注意,服务配置是一个配置对象,除非您以某种方式沿其默认路径更改它,否则它也会被设置为瞬态:
public MediatRServiceConfiguration()
{
MediatorImplementationType = typeof(Mediator);
Lifetime = ServiceLifetime.Transient;
}
【讨论】:
使用核心,您可以手动注册您的处理程序并使用您想要的任何范围。比如:
services.AddScoped<IPipelineBehavior<MyCommand>, MyHandler>();
我们实际上包装了 Mediatr,因此我们可以添加各种位和 bobs,因此它最终成为这样的注册扩展(CommandContect/QueryContext 包含我们一直使用的各种东西,而 ExecutionResponse 是标准响应,因此我们可以拥有标准 post 知道他们得到什么的处理程序):
public static IServiceCollection AddCommandHandler<THandler, TCommand>(this IServiceCollection services)
where THandler : class, IPipelineBehavior<CommandContext<TCommand>, ExecutionResponse>
where TCommand : ICommand
{
services.AddScoped<IPipelineBehavior<CommandContext<TCommand>, ExecutionResponse>, THandler>();
return services;
}
这样使用:
services.AddCommandHandler<MyHandler, MyCommand>();
我们有类似的查询(AddQueryHandler<.....>
希望有帮助
【讨论】: