2013-10-21 4 views
1

RavenDB 및 RavenUserAuthRepository 패키지와 함께 ServiceStack 인증 플러그인을 즉시 사용하려고합니다.RavenDB를 사용할 때 후속 ServiceStack OAuth 시도가 실패 함 (NonUniqueObjectException)

AppHost

var store = new DocumentStore() 
     { 
      ConnectionStringName = "ServiceStackAuthSample" 
     } 
      .Initialize(); 

     IndexCreation.CreateIndexes(typeof(RavenUserAuthRepository).Assembly, store); 

     container.Register(store); 
     var session = container.Resolve<IDocumentStore>().OpenSession(); 
     container.Register(p => session).ReusedWithin(ReuseScope.Request); 

     container.Register<IUserAuthRepository>(p => new RavenUserAuthRepository(p.Resolve<IDocumentStore>(), p.Resolve<IDocumentSession>())); 

페이스 북, GoogleOAuth, 트위터를 통해 첫 번째 인증 시도 - 예상대로 작동합니다. 내가 재 인증을 시도 할 경우, RavenDB는 그것을 좋아하지 않는 것 그리고 난 다음 얻을 :

오류가 UserAuths 'ID를 가진 다른 객체를 연결하는 CodeNonUniqueObjectExceptionmessageAttempted/[인증을 추적 1'.stack : 2011 년 10 월 21 일 6시 51 분 4 초] : [요청 : {provider : facebook}] Raven.Client.Exceptions.NonUniqueObjectException : 다른 객체를 'UserAuths/1'ID와 연결하려고 시도했습니다. c : \ Builds \ RavenDB-Stable \ Raven.Client.Lightweight \ Document \ InMemoryDocumentSessionOperations.cs의 Raven.Client.Document.InMemoryDocumentSessionOperations.AssertNoNonUniqueInstance (Object 엔터티, 문자열 ID) : Raven.Client.Document.InMemoryDocumentSessionOperations의 778 줄. RavenDB-Stable \ Raven.Client.Lightweight \ Document \ InMemoryDocumentSessionOperations.cs : Raven.Client.Document.InMemoryDocumentSessionOperations.Store (Object())에서 670 번째 줄에있는 StoreInternal (개체 엔터티, Etag etag, 문자열 ID, 부울 forceConcurrencyCheck) RavenDB-Stable \ Raven.Client.Lightweight \ Document \ InMemoryDocumentSessionOperations.cs : ServiceStack.Authentication.RavenDb.RavenUserAuthRepository.CreateOrMergeAuthSession (IAuthSession authSession, IOAuthTokens 토큰)의 608 줄을 ServiceStack.ServiceInterface.Auth에서 가져옵니다. AuthProvider.OnAuthenticated (IServiceBase authService, IAuthSession 세션, IOAuthTokens 토큰, 사전 2 authInfo) at ServiceStack.ServiceInterface.Auth.FacebookAuthProvider.Authenticate(IServiceBase authService, IAuthSession session, Auth request) at ServiceStack.ServiceInterface.Auth.AuthService.Authenticate(Auth request, String provider, IAuthSession session, IAuthProvider oAuthConfig) at ServiceStack.ServiceInterface.Auth.AuthService.Post(Auth request) at lambda_method(Closure , Object , Object) at ServiceStack.ServiceHost.ServiceRunner) 1.Execute (IRequestContext requestC ontext, 객체 인스턴스, TRequest 요청)

RavenDB 검색은 내 세션과 관련이 있다고 말하지만 여기서 잘못된 점을 분명히하지 못합니다. ServiceStack에서 RavenDB 세션을 관리하는 방법을 이해할 수 있습니다.

UPDATE

ServiceStack.AuthenticationRavenDb.RavenUserAuthRepository :: GetUserAuth 방법의 V3 지점에서 문제가 있었다 밝혀졌습니다. 다른 모든 메소드가 생성자에 의해 삽입 된 개인 IDocumentSession 멤버를 사용하는 동안 GetUserAuth는 IDocumentSession의 새로운 인스턴스를 생성합니다. 고정

private readonly IDocumentStore _documentStore; 

public RavenUserAuthRepository(IDocumentStore documentStore,IDocumentSession session) 
{ 
    _documentStore = documentStore; 
    _session = session; 
} 

올드

public UserAuth GetUserAuth(string userAuthId) 
{ 
    using (var session = documentStore.OpenSession()) 
    { 
     int intAuthId; 
     return int.TryParse(userAuthId, out intAuthId) 
      ? session.Load<UserAuth>(intAuthId) 
      : session.Load<UserAuth>(userAuthId); 
    } 
} 

public UserAuth GetUserAuth(string userAuthId) 
{ 
    using (_session) 
    { 
     int intAuthId; 
     return int.TryParse(userAuthId, out intAuthId) 
      ? _session.Load<UserAuth>(intAuthId) 
      : _session.Load<UserAuth>(userAuthId); 
    } 
} 

이 리드 CreateOrMergeAuthSession 후 개인 세션을 사용하여, (GetUserAuth를 통해) 하나 개의 세션 인스턴스가 UserAuth을 받고 에 회원이 UserA를 저장합니다. 어, 충돌을 일으켰 어.

팁 주셔서 감사합니다, David!

답변

1

여기에 나와있는 ServiceStack DI API에 익숙하지 않지만 하나의 DocumentStore를 만들고 등록하는 것처럼 보이지만 하나의 IDocumentSession을 만들고 그 인스턴스 만 등록하는 것처럼 보입니다. .모든 요청에 ​​대해 IDocumentSession의 고유 한 인스턴스가 있어야하므로 모든 요청이 DocumentStore의 OpenSession 메서드를 호출하도록 컨테이너를 구성해야합니다.

관련 문제