Как разрешить «зарегистрирован как стиль жизни« Async Scoped », но экземпляр запрашивается вне контекста активной области действия (Async Scoped)» - PullRequest
2 голосов
/ 23 сентября 2019

Я использую TopShelf, Quartz и SimpleInjector.Таким образом, у меня продолжает возникать это исключение, я пытался создать гибрид, но в итоге

"зарегистрирован как стиль жизни 'Гибридная асинхронная область / веб-запрос', но экземпляр запрашивается вне контекста активного (Гибридная асинхроннаяScoped / Web Request) scope "

Когда я не использую simpleinjector и просто вызываю класс без передачи интерфейсов в конструкторе, он вызывает метод Start, но если я использую simpleinjector, он невызовите указанный FooService:

HostFactory.Run(config =>
{
    config.SetServiceName("Foo Scheduler");
    config.SetDisplayName("Foo Scheduler");
    config.RunAsLocalSystem();
    config.UseSimpleInjector(container);
    config.StartAutomatically();

    config.Service<IFooService>(scheduler =>
    {
        scheduler.ConstructUsingSimpleInjector();
        scheduler.WhenStarted((s, c) => s.Start());
        scheduler.WhenStopped((s, c) => s.Stop());
    });
});

Вот трассировка стека ошибок:

Topshelf v4.2.1.215, .NET Framework v4.0.30319.42000 Ошибка Topshelf.HostFactory:0: возникла исключительная ситуация при создании хоста, Topshelf.ServiceBuilderException: возникла исключительная ситуация при создании службы: IFooService ---> SimpleInjector.ActivationException: FooService зарегистрирован как образ жизни с асинхронной областью действия, но экземпляр запрашивается вне контекста активногоОбласть действия (асинхронная).Пожалуйста, см. https://simpleinjector.org/scoped для получения дополнительной информации о том, как управлять областями.в SimpleInjector.Scope.GetScopelessInstance [TImplementation] (регистрация Scoped 1 registration) at SimpleInjector.Scope.GetInstance[TImplementation](ScopedRegistration 1, область действия) в SimpleInjector.Advanced.Internal.LazyScopedRegistration 1.GetInstance(Scope scope) at lambda_method(Closure ) at SimpleInjector.InstanceProducer.GetInstance() at SimpleInjector.Container.GetInstanceFromProducer(InstanceProducer instanceProducer, Type serviceType) at SimpleInjector.Container.GetInstanceForRootType[TService]() at SimpleInjector.Container.GetInstance[TService]() at Topshelf.SimpleInjector.ServiceConfiguratorExtensions.<>c__0 1.b__0_0 (HostSettings serviceFactory) в Topshelf.Builders.Delegate(Настройки HostSettings) в Topshelf.Builders.RunBuilder.Build (ServiceBuilder serviceBuilder) в Topshelf.HostConfigurators.HostConfiguratorImpl.CreateHost () в Topshelf.HostFactory.New (Действие * регистрация 1015 * 1) в простой точкеScopedRegistration 1 registration, Scope scope) at SimpleInjector.Advanced.Internal.LazyScopedRegistration 1.GetInstance (область видимости) в lambda_method (закрытие) в SimpleInjector.InstanceProducer.GetInstance () в SimpleInjector.Container.GetInstanceFromProducer (InstanceProducer instanceProducer, тип serviceType) в SimpleInjector.ConstanceTerGerTopshelf.SimpleInjector.ServiceConfiguratorExtensions. <> C__0 1.<ConstructUsingSimpleInjector>b__0_0(HostSettings serviceFactory) at Topshelf.Builders.DelegateServiceBuilder 1.Build (настройки HostSettings) --- Конец внутреннего исключениятрассировка стека --- в Topshelf.Builders.DelegateServiceBuilder 1.Build(HostSettings settings) at Topshelf.Builders.RunBuilder.Build(ServiceBuilder serviceBuilder) at Topshelf.HostConfigurators.HostConfiguratorImpl.CreateHost() at Topshelf.HostFactory.New(Action 1 configureCallback) в Topshelf.HostFactory.Run (Action`1 configureCallback)

РЕДАКТИРОВАТЬ: Мой контейнер простого инжектора содержит следующее:

var container = new Container();
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
container.RegisterInstance<IJobFactory>(new SimpleInjectorJobFactory(container));
var quartzSchedulerFactory = new StdSchedulerFactory();
container.RegisterInstance<ISchedulerFactory>(quartzSchedulerFactory);
container.RegisterInstance<IScheduler>(await quartzSchedulerFactory.GetScheduler());
container.Register<IJobListener, CtrackJobListener>(Lifestyle.Scoped);
container.Register<ISchedulerService, SchedulerService>(Lifestyle.Scoped);

1 Ответ

0 голосов
/ 24 сентября 2019

Итак, я уже решил ответ, прочитав следующий URL: https://simpleinjector.readthedocs.io/en/latest/decisions.html#don-t-allow-resolving-scoped-instances-outside-an-active-scope

Это просто означало, что используемый образ жизни не подходит для определенного набора классов (например, вы используете принудительную асинхронную область или другое,но это должен был быть одноэлементный или временный)

Оказывается, что все классы, использующие или наследующие DbContext, и те, которые используют HttpClient, должны использовать "Lifestyle.Singleton", и если у них есть какие-либо зависимости (то есть был добавлен другой класс)в них), тогда они также должны использовать Lifestyle.Singleton.

Я закончил тем, что использовал гибрид, и применил этот образ жизни ко ВСЕМ другим введенным классам (кроме тех, которые используют синглтоны)

var lifeStyle = Lifestyle.CreateHybrid(
                 lifestyleSelector: () => HttpContext.Current != null,
                 trueLifestyle: new AsyncScopedLifestyle(),
                 : Lifestyle.Transient);

Я надеюсь, что это может помочь кому-то еще в будущем.

...