您正在尝试解决跨线服务,但在使用 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 InjectorSimpleRabbit 将消息发布到 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工作?

visio直线交叉相交跨线修改

您无权访问此服务器上的 /admin/add.php

如何在 CentOS 7 上安装 perl-RRD-Simple 软件包?

使用 Fetch API 将数据发送到 PHP 服务器(首选 POST 方法和 JSON)

pip安装出现超时问题(超时)解决方案