Mediatr范围问题 [英] Mediatr Scope problems

查看:224
本文介绍了Mediatr范围问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Mediatr处理来自队列的消息.我可以得到一个简单的例子来工作.但是,当我尝试向处理程序中注入对象时遇到了问题

I am using Mediatr to handle messages from a queue. I can get a simple example to work. However I have run into problems when I try to inject an object into my handler

public class MessageCommandHandler : IRequestHandler<MessageCommand, bool>
    {
        private IMyDependency myDependency;
        public MessageCommandHandler(IMyDependency myDependency)
        {
            this.myDependency = myDependency;
        }

        public Task<bool> Handle(MessageCommand request, CancellationToken cancellationToken)
        {
            return Task.FromResult(true);
        }
    }

这仅在我将IMyDependency注册为临时范围时有效,但是当我将其注册为范围生存期时,它将失败并显示错误

This only works when I register IMyDependency as a transient scope, however when I register it as scoped lifetime it fails with the error

Cannot resolve 'MediatR.IRequestHandler`2[MyNamespace.MessageCommand,System.Boolean]' from root provider because it requires scoped service 'MyNamespace.IMyDependency'

我需要能够注入具有范围内生存期的依赖项.有没有人对此有解决方案.

I need to be able to inject dependencies with scoped lifetime. Has anyone got a solution for this.

我正在使用.NET Core依赖项注入框架.设置如下

I am using the .NET Core dependency injection framework. It is setup as follows

services.AddHostedService<QueueConsumer>();
            services.AddScoped<IMyDependency, MyDependency>();
            services.AddMediatR(new Assembly[] { Assembly.GetExecutingAssembly() });

有什么想法吗?

推荐答案

每当您使用具有作用域生存期的依赖项时,都需要在预先创建的作用域内使用它.对于MVC,这将在幕后自动发生,但是如果您直接使用自己的代码(例如通过控制台应用程序等)使用,则需要自己创建范围.

Any time you use a dependency with a Scoped lifetime, you will need to use it inside a pre-created scope. In the case of MVC this would happen automatically behind the scenes but if you're using direct from your own code, say via a console application or something, you will need to create the scope yourself.

这可以通过注入IServiceScopeFactory的实例,然后使用此工厂创建作用域,然后从该作用域中检索依赖项来完成,例如

This can be done by injecting an instance of IServiceScopeFactory and then using this factory to create a scope and then retrieve the dependency from that scope e.g.

public class MessageCommandHandler : IRequestHandler<MessageCommand, bool>
    {
        private IServiceScopeFactory _serviceScopeFactory;

        public MessageCommandHandler(IServiceScopeFactory serviceScopeFactory) 

        {
            _serviceScopeFactory = serviceScopeFactory;
        }

        public Task<bool> Handle(MessageCommand request, CancellationToken cancellationToken)
        {
            using (var scope = _serviceScopeFactory.CreateScope())
            {
                var scopedServices = scope.ServiceProvider;
                var myDependency = scopedServices.GetRequiredService<IMyDependency>();
                return Task.FromResult(true);
            }
        }
    }

但是(请注意,上面的代码未经测试),在我自己的系统中,我几乎总是围绕发送中介请求的内容创建作用域,在这种情况下,任何作用域依赖项仍将自动注入该作用域,例如

However (and note that the code above is untested), in my own systems I would almost always create the scope around whatever is sending the mediator request in which case any Scoped dependencies will still be injected automatically at this scope e.g.

... // some other calling class / Main method etc..

using (var scope = _serviceScopeFactory.CreateScope())
    var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
    mediator.Send(new MessageCommand());
}

这篇关于Mediatr范围问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆