【问题标题】:Simple Injector instance is requested outside the context of an active (async scope) scope在活动(异步范围)范围的上下文之外请求简单的 Injector 实例
【发布时间】:2023-03-13 08:21:01
【问题描述】:

我正在尝试使用 SimpleInjector 将我的 IAuthorizationRepository 注入到我的 VB Web 应用程序中。

Public Class IdentityPackage
    Implements IPackage
    Public Sub RegisterServices(container As Container) Implements IPackage.RegisterServices
        container.Register(Of IUserStore(Of User, Integer), UserStore)(Lifestyle.Scoped)
        container.Register(Of IAuthorizationRepository, AuthorizationRepository)(Lifestyle.Scoped)
        container.Register(Of ISession, Session)()
    End Sub
End Class

这是我的创业公司。

Public Partial Class Startup
    Public Sub Configuration(app As IAppBuilder)
        Dim container = ConfigureSimpleInjector(app)
        Dim config = New HttpConfiguration() With {
            .DependencyResolver = New SimpleInjectorWebApiDependencyResolver(container)
        }

        ConfigureOAuth(app, container)

        WebApiConfig.Register(config)
        app.UseCors(CorsOptions.AllowAll)
        app.UseWebApi(config)
    End Sub
End Class

这是我的 ConfigureOAuth。

Public Sub ConfigureOAuth(app As IAppBuilder, container As Container)
    Dim authRepositoryFactory As Func(Of IAuthorizationRepository) = container.GetInstance(Of IAuthorizationRepository)

    Dim authorizationOptions = New OAuthAuthorizationServerOptions() With {
        .AllowInsecureHttp = True,
        .TokenEndpointPath = New PathString("/api/token"),
        .AccessTokenExpireTimeSpan = TimeSpan.FromHours(4),
        .Provider = New AuthorizationServerProvider(authRepositoryFactory)
    }

    ' Token Generation
    app.UseOAuthAuthorizationServer(authorizationOptions)
    app.UseOAuthBearerAuthentication(New OAuthBearerAuthenticationOptions())
End Sub

当它到达ConfigureOAuth下的第一行时,它会抛出错误The AuthorizationRepository is registered as 'Async Scoped' lifestyle, but the instance is requested outside the context of an active (Async Scoped) scope.

奇怪的是,我正在将一个现有的、功能齐全的 C# 项目转换为 VB,这是 C# 中代码库的 VB 等价物,但 C# 代码没有这个问题。这让我觉得问题在于 VB 如何处理代码,而不是 C#,但我看不出这个例子是怎么回事。谁能告诉我怎么回事?

以下是我的堆栈跟踪:

[ActivationException: The AuthorizationRepository is registered as 'Async Scoped' lifestyle, but the instance is requested outside the context of an active (Async Scoped) scope.]
   SimpleInjector.Scope.GetScopelessInstance(ScopedRegistration`1 registration) +168
   SimpleInjector.Scope.GetInstance(ScopedRegistration`1 registration, Scope scope) +52
   SimpleInjector.Advanced.Internal.LazyScopedRegistration`1.GetInstance(Scope scope) +158
   lambda_method(Closure ) +223
   SimpleInjector.InstanceProducer.BuildAndReplaceInstanceCreatorAndCreateFirstInstance() +32
   SimpleInjector.InstanceProducer.GetInstance() +235
   SimpleInjector.Container.GetInstanceForRootType() +154
   SimpleInjector.Container.GetInstance() +146
   ClientWebAppVB.Api.Startup.ConfigureOAuth(IAppBuilder app, Container container) in C:\Projects\TEST\ClientWebAppVB\ClientWebAppVB.Api\App_Start\OAuthConfig.vb:10
   ClientWebAppVB.Api.Startup.Configuration(IAppBuilder app) in C:\Projects\TEST\ClientWebAppVB\ClientWebAppVB.Api\Startup.vb:15

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
   System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +160
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +101
   Owin.Loader.<>c__DisplayClass12.<MakeDelegate>b__b(IAppBuilder builder) +66
   Owin.Loader.<>c__DisplayClass1.<LoadImplementation>b__0(IAppBuilder builder) +123
   Microsoft.Owin.Host.SystemWeb.<>c__DisplayClass2.<InitializeBlueprint>b__0(IAppBuilder builder) +71
   Microsoft.Owin.Host.SystemWeb.OwinAppContext.Initialize(Action`1 startup) +462
   Microsoft.Owin.Host.SystemWeb.OwinBuilder.Build(Action`1 startup) +40
   Microsoft.Owin.Host.SystemWeb.OwinHttpModule.InitializeBlueprint() +70
   System.Threading.LazyInitializer.EnsureInitializedCore(T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory) +115
   Microsoft.Owin.Host.SystemWeb.OwinHttpModule.Init(HttpApplication context) +106
   System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +536
   System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +173
   System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +336
   System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +296

[HttpException (0x80004005): Exception has been thrown by the target of an invocation.]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +10044576
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +95
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +254

【问题讨论】:

  • 今天的教训:不要使用 VB。

标签: vb.net simple-injector


【解决方案1】:

奇怪的是,我正在将一个现有的、功能齐全的 C# 项目转换为 VB,这是 C# 中代码库的 VB 等价物,但 C# 代码没有这个问题

这实际上并不等同于 c# 版本。除非您更改 Option ExplicitOption Strict 设置,否则我很确定您显示的代码甚至无法编译。或者在您的真实代码中,您省略了 As Func(Of IAuthorizationRepository) 子句。

在 c# 中,这两行是完全不同的两件事:

// create a delegate
Func<IAuthorizationRepository> authRepositoryFactory = 
                        container.GetInstance<IAuthorizationRepository>;
// and directly call a delegate or method
Func<IAuthorizationRepository> authRepositoryFactory = 
                        container.GetInstance<IAuthorizationRepository>();

这里第二行没有编译。此行返回IAuthorizationRepository,因此不能分配给Func&lt;IAuthorizationRepository&gt;

但在 Vb.Net 中,以下几行完全相同。方法调用的大括号是完全可选的。

' Directly call the method
Dim authRepositoryFactory = container.GetInstance(Of IAuthorizationRepository)
' And directy call the method
Dim authRepositoryFactory = container.GetInstance(Of IAuthorizationRepository)()

如果您将鼠标悬停在 authRepositoryFactory 上,您会看到两条线的推断类型均为 IAuthorizationRepository

要创建委托而不是直接在 VB 中调用它,您需要使用 AddressOf Operator

Dim authRepositoryFactory = New Func(Of IAuthorizationRepository)(
              AddressOf container.GetInstance(Of IAuthorizationRepository))

'or
Dim authRepositoryFactory As Func(Of IAuthorizationRepository) =
              AddressOf container.GetInstance(Of IAuthorizationRepository)

如果您将鼠标悬停在 authRepositoryFactory 上,您会发现这实际上是 Func (Of IAuthorizationRepository)

【讨论】:

  • 啊该死的。谢谢你。我完全错过了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-22
  • 2013-06-29
  • 1970-01-01
  • 2020-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多