您正在尝试解决跨线服务,但在使用 Simple Injector 的活动(Async Scoped)范围之外执行此操作
Posted
技术标签:
【中文标题】您正在尝试解决跨线服务,但在使用 Simple Injector 的活动(Async Scoped)范围之外执行此操作【英文标题】:You are trying to resolve a cross-wired service, but are doing so outside the context of an active (Async Scoped) scope with Simple Injector 【发布时间】:2021-08-07 08:51:49 【问题描述】:我正在构建一个 .NET Core 控制台应用程序,它使用 Simple Injector 和 SimpleRabbit 将消息发布到 RabbitMQ。
当我尝试从容器中获取注册实例时遇到了运行时异常。 为了获得指导,我一直在尝试按照此链接中的说明进行操作:SimpleInjector integration documentation
下面的代码 sn-p 概述了我在使用 HostBuilder、配置和 注册所需的服务。
主要:
public static async Task Main(string[] args)
var configurationRoot = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.Build();
// Initialize the SimpleInjector container
var searchJobStatus = new SearchJobTrackerModel();
Bootstrap.ConfigureServices(configurationRoot);
var container = Bootstrap.container;
var builder = new HostBuilder()
.ConfigureAppConfiguration((hostingContext, config) =>
config.AddJsonFile(
"appsettings.json", optional: true, reloadOnChange: true);
)
.ConfigureServices((context, services) =>
services.AddSimpleInjector(container, options => );
services.AddRabbitConfiguration(
configurationRoot.GetSection("RabbitConfiguration"))
.AddSubscriberConfiguration(
configurationRoot.GetSection("Subscribers"))
.AddPublisherServices()
.AddSubscriberServices()
.AddSingletonMessageHandler<DiscoverySubscriberService>()
.AddSingleton<IQueueManagementService, QueueManagementService>()
.AddSingleton<IHostedService, DiscoveryConsoleService>();
);
await builder.RunConsoleAsync();
引导程序:
public class Bootstrap
public static Container container;
public static void ConfigureServices(IConfigurationRoot configurationRoot)
container = new SimpleInjector.Container();
container.Options.ResolveUnregisteredConcreteTypes = false;
container.Options.EnableAutoVerification = false;
RabbitConfiguration rabbitConfiguration = new RabbitConfiguration();
configurationRoot.GetSection("RabbitConfiguration").Bind(rabbitConfiguration);
container.ConfigureServices(rabbitConfiguration);
public static class ServicesInstaller
public static void ConfigureServices(
this Container container, RabbitConfiguration rabbitConfiguration)
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
container.Options.ResolveUnregisteredConcreteTypes = false;
// Rabbit Configuration
container.RegisterInstance<RabbitConfiguration>(rabbitConfiguration);
container.RegisterSingleton<IMessagePublisher, MessagePublisher>();
出版商和经理:
public class MessagePublisher : IMessagePublisher
IPublishService publisher;
public IMessagePublisher(IPublishService publisher)
this.publisher = publisher;
public class Manager : IManager
public Manager(IMessagePublisher publisher)
我尝试获取 IManager 实例:
var manager = Container.GetInstance<IManager>();
我得到以下运行时异常:
SimpleInjector.ActivationException HResult=0x80131500 消息=解析交叉连接的 IPublishService 时出错。您正在尝试解析跨线服务,但在活动(异步作用域)范围的上下文之外执行此操作。为了能够解析此服务,操作必须在此类范围的上下文中运行。有关如何管理范围的更多信息,请参阅https://simpleinjector.org/scoped。
我认为问题在于 .AddPublisherServices()
将发布者服务添加到我的服务集合和 Manager
类的构造函数之间:
public Manager(IMessagePublisher publisher)
这就是我所能缩小的范围。
我构建容器和添加/注册服务的方式是否有错误?
AddPublisherServices
使用的范围是否与我的容器中定义的服务冲突?
【问题讨论】:
【参考方案1】:异常状态:
您正在尝试在 ... Async ... 范围的上下文之外解析 ... 服务 ...。
换句话说,将操作包装在对using (AsyncScopedLifestyle.BeginScope(container)
的调用中。例如:
await using (AsyncScopedLifestyle.BeginScope(container))
var manager = container.GetInstance<IManager>();
await manager.DoSomethingWithMessages(myMessage);
欲了解更多信息,请参阅the documentation。
【讨论】:
我没有在我的任何代码中显式调用 AsyncScopedLifestyle.BeginScope()。当我获取接口实例时抛出异常;这当然会强制对包含的依赖项进行构造函数调用。 @JohnB:如果您之前的评论是个问题,请改写。以上是关于您正在尝试解决跨线服务,但在使用 Simple Injector 的活动(Async Scoped)范围之外执行此操作的主要内容,如果未能解决你的问题,请参考以下文章
如何在Visual Studio代码中使用FTP-Simple工作?
如何在 CentOS 7 上安装 perl-RRD-Simple 软件包?