2017-07-07 20 views
0

我試圖使用SimpleInjector將我的IAuthorizationRepository注入到我的VB Web App中。在活動(異步範圍)範圍的上下文之外請求簡單注入器實例

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,這就是VB中的代碼等同於C#中的代碼庫,但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 
+1

課:不要使用VB。 – Steven

回答

2

奇怪的是,我將現有的,功能齊全的C#項目到VB,這是VB等價代碼庫中C#,但C#代碼沒有這個問題

那麼這實際上不是相當於c#版本。除非你改變了Option ExplicitOption Strict設置我很確定你所顯示的代碼甚至沒有編譯。或者在您真實的代碼中,您省略了As Func(Of IAuthorizationRepository)條款。

在C#這兩條線是2個完全不同的東西:

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

在這裏,第二行不能編譯。此行返回IAuthorizationRepository,因此不能分配給Func<IAuthorizationRepository>

但是在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)

+0

啊,天哪,該死的。謝謝。我完全錯過了。 –