2

내 마지막 question about fine-tuning에 대한 모든 답이 예상 한 것보다 더 유용하다는 것이 밝혀진 후에도 MembershipProviders에 대한 또 다른 비슷한 질문을 할 것이라고 생각했습니다.회원 공급자를 미세 조정하는 방법은 무엇입니까?

좋아요, 우선, 명확히하기 : 회원 자격, 역할 및 프로필 제공 업체가 무엇인지, 내 자신을 구현하는 방법, 구성 방법 및 구성 방법 및 대부분의 사항을 알고 있습니다.
역할 및 프로필 공급자를 구현하는 것은 대부분 간단한 CRUD 만 필요하기 때문에 매우 간단합니다. LINQ의 한 줄로 RoleProvider의 메서드 중 절반 정도는 충분합니다.

그러나 회원 공급자는 다른 짐승입니다. 많은 사람들이 SR (Single Responsibility) 원칙에 위배된다는 것을 깨닫게 될 것입니다. 왜냐하면 그것은 사용자 관리와 관련된 모든 것을해야하기 때문입니다. 이것은 커스터마이징을위한 많은 공간을 남겨 두지 만, 단점도 가지고 있습니다. 인터넷에 예외 상황을 던지거나 단순히 null을 반환해야 할 때와 같이 예상되는 동작이 무엇인지에 대한 정보는 없습니다.

참고로 this sample implementation을 사용하지만 몇 가지 모순이 있습니다.

  • 예를 들어, 자체 ValidateUser 메서드를 사용하여 ChangePassword 메서드의 자격 증명을 확인합니다. 그러나 ValidateUser는 또한 사용자의 LastLoginDate를 현재 날짜로 업데이트합니다. 그래서 프레임 워크는 필자 자신의 공급자에서도이 프레임 워크를 설정할 것을 기대합니까? 아니면 단순히 샘플에서 실수입니까?
  • 다른 하나는 ChangePassword 메서드가 새 암호의 유효성을 검사 할 때마다 예외를 throw하지만 CreateUser는 예외를 throw하지 않고 단순히 false를 반환한다는 것입니다.
  • 마지막으로 사용자의 유효하지 않은 암호 시도 횟수를 계산하고 임계 값을 초과하면 잠급니다. 이것은 좋은 일이지만 사용자 잠금을 해제하려면 수동 조치가 필요합니다. 일정 시간이 지난 후에 공급자가 자동으로 사용자의 잠금을 해제하면 문제가 발생합니까?

  • (EDIT) 거의 잊어 버렸습니다. 샘플의 CreateUser 메소드는 method 매개 변수에서 ID를 삽입합니다. 실제로 자동 인서트를 ID로 사용하기 때문에 이것이 나쁜 습관이라고 생각합니다. 따라서 일부 메소드 매개 변수에서 자동 인서트를 삽입하는 것은 옵션이 아닙니다. 매개 변수를 그냥 무시해야합니까, 아니면 매개 변수의 값이 null이어야하고 그렇지 않으면 예외를 throw해야합니까?

전체적으로 ASP.NET에는 MembershipProvider의 동작에 대한 가정이 있습니까?
예외를 throw해야하는시기 또는 null을 반환해야하는 경우를 설명하는 문서가 있습니까?

예상되는 동작에 대한 지침을 제공하는 일반적인 단위 테스트 집합도 찾으려고했지만 행운은 없었습니다. "단위 테스트가 좋음"및 "단위 테스트 방법에 대한 기사가 많이 있습니다." "하지만 실제 테스트가있는 곳은 아닙니다.

미리 감사드립니다.

답변

4

안내를 위해 MSDN에 문의 할 수 있습니다.예를 들어, RoleProvider.RemoveUsersFromRoles 다음과 같은 지침을 제공

RemoveUsersFromRoles가 에 지정된 역할에서 지정된 사용자를 제거하는 RemoveUserFromRole, RemoveUsersFromRole, RemoveUserFromRoles 및 역할 클래스의 RemoveUsersFromRoles 방법에 의해 호출

데이터 소스. 구성된 ApplicationName의 역할 만 입니다. 지정된 역할 이름 중 하나가 구성된 applicationName에 대한 찾을 수없는 경우

, 우리는 당신의 공급자가 않고 ​​ProviderException을 던져 하는 것이 좋습니다. 지정된 사용자 이름 중 하나가 applicationName에 구성된 에 대한 지정된 역할 이름 중 하나와 연관되지 을 경우

, 우리는 당신의 공급자가 않고 ​​ProviderException를 던질 것이 좋습니다 .

지정된 사용자 이름이 이거나 null이거나 빈 문자열 인 경우 은 제공자가 예외를 throw 할 것을 권장합니다. 지정된 역할 이름 중 하나가 널 (null) 또는 빈 문자열 인 경우

, 우리는 공급자가 예외를 throw하는 것이 좋습니다 . 데이터 소스가 트랜잭션을 지원하는 경우

, 우리는 당신이 이 각각 트랜잭션에서 제거 작업을하고 트랜잭션을 롤백하고 어떤 제거 작업이 실패 할 경우 예외를 던질 것을 포함하는 것이 좋습니다.

그리고 RoleProvider.GetRolesForUser는 말한다 :

GetRolesForUser 지정된 사용자가 데이터 소스와 연관된 역할 이름을 검색 할 수있는 역할 클래스의 GetRolesForUser 방법에 의해 호출됩니다. 구성된 ApplicationName의 역할 만 검색됩니다.

구성된 applicationName에 대해 지정된 사용자에 대한 역할이 없으면 공급자가 요소없이 문자열 배열을 반환하는 것이 좋습니다.

지정된 사용자 이름이 null이거나 빈 문자열 인 경우 공급자가 예외를 throw하는 것이 좋습니다.

그러나 실제로는 각 공급자에서 필요하고 예상되는 몇 가지 방법과 동작 만 있습니다. 나머지는 구현하려는 기능을 지원합니다.

기본 공급자 스택을 다루는 데 수년이 걸린 후 링크 대상 샘플과 관련하여 몇 가지 사항을 이해하게되었습니다.이 샘플은 모서리를 자르는 매우 간단한 구현입니다 (예 : ChangePassword 메서드입니다.

반사경을 사용하고 SqlMembershipProvider를 살펴보면 몇 가지 중요한 차이점을 발견 할 것입니다 ...예를 들어

: 물론, 사용자가 로그인되어 있기 때문에

  • ValidateUser 업데이트 날짜 로그인이 UpdateLastLoginTime에 대한 사실과 .CheckPassword를 호출하여 그렇게. 비밀번호 변경은 동일한 메소드를 호출하지만 false를 제공합니다.

  • SPROC도 UserId 매개 변수를 허용하므로 CreateUser 메서드는 ProviderUserKey를 허용합니다. 이것은 멤버쉽 테이블과 사용자 테이블 간의 레크리에이션과 동기화를 허용하기위한 것입니다. API의 소비자는 일반적으로이 기능을 사용하지 않지만 공급자 스택은 내부적으로 수행합니다.

  • 잠금에 관해서 .. 당신에게 달려 있습니다. 즉, 사용자 지정 공급자를 구현하는 것, 즉 원하는 동작을 얻는 것입니다. 내가 말했듯이 체계적인 요구 사항은 거의 없습니다. 공급자의 동작 이후

    은 크게 임의 ... 행동과 단위 테스트 예상 :

그래서,이 (두 단락이 같은 우려에 암시) 질문의 마지막 부분에 우리를 제공합니다 예상되는 행동이 거의 없지만 확립 된 일련의 일반 테스트에는 매우 적은 수의 방법이 포함됩니다. 구현의 동작에 적용되는 테스트를 작성해야합니다.

마지막으로, finddownload Asp.Net 공급자 도구 키트 샘플을 제안합니다. 완전한 SQL 공급자 스택을위한 작업 소스 코드를 제공하고 '실제'공급자가 어떻게 구현되는지에 대한 통찰력을 줄 것입니다. 뒤늦게 추가

:이 순간에서

, 나는 기본 SQL 스택과 100 % 호환되는 전체 SQLite는 공급자 스택을 구현하고있다. 테스트 스위트는 내 스택과 asp.net 사이의 행동 패리티를 확인합니다. 내 프로필을 통해 내 블로그를 조회하고 저에게 연락하는 경우 테스트가 완료되면 알려 드리며 기본 스택에서 정확히 예상되는 것을 벤치 마크로 사용할 수 있습니다.

+0

+1. 귀하의 답변에 감사드립니다. 그러나 가장 중요한 부분은 생략했습니다. 어느 메소드에서 예외를 던져야하며, 단지 거짓 (또는 null, 해당되는 경우)을 반환해야합니까? – Venemo

+0

@ 베네모 - 주관적인 안내뿐만 아니라 요구하는 '공식적인'지침을 제공하는 답변을 업데이트했습니다. –

+0

대단히 고마워,이게 내가 찾고 있었던 바로 그거야. :) 나는 MSDN이 그런 결정적인 가이드를 가지고 있다는 것을 몰랐다. (아, 괜찮 으면 블로그에 연락하겠습니다.) – Venemo