2017-07-07 56 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

啊,天哪,该死的。谢谢。我完全错过了。 –