您正在尝试解决跨线服务,但在使用 Simple Injector 的活动异步范围范围的上下文之外执行此操作

问题描述

我正在构建一个 .NET Core 控制台应用程序,该应用程序使用 Simple InjectorSimpleRabbit 将消息发布到 RabbitMQ

当我尝试从容器中获取注册实例时遇到了运行时异常。 作为指导,我一直在尝试按照此链接中的说明进行操作:SimpleInjector integration documentation

下面的代码片段概述了我在使用 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",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 Message=解析交叉连接的 IPublishService 时出错。您正在尝试解析跨线服务,但在活动(异步范围)范围的上下文之外执行此操作。为了能够解析此服务,操作必须在此类范围的上下文中运行。有关如何管理范围的详细信息,请参阅 https://simpleinjector.org/scoped

我认为问题在于将发布者服务添加到我的服务集合的 .AddPublisherServices()Manager 类上的构造函数之间:

public Manager(IMessagePublisher publisher)

这是我能够缩小范围的范围。 我构建容器和添加/注册服务的方式是否有错误AddPublisherServices 使用的范围是否与我的容器中定义的服务冲突?

解决方法

异常状态:

您正在尝试在...异步...范围的上下文之外解析...服务...。

换句话说,将操作包装在对 using (AsyncScopedLifestyle.BeginScope(container) 的调用中。例如:

await using (AsyncScopedLifestyle.BeginScope(container))
{
    var manager = container.GetInstance<IManager>();

    await manager.DoSomethingWithMessages(myMessage);
}

有关详细信息,请参阅 the documentation

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...