properties 요소를 보도록 하자.
defaultValue 라는 것은 기본 설정 값이다. Role의 경우 인증을 하지 않으면 기본적으로 Anonymous라는 역할을 할당한다는 의미가 되겠다. 이로서 인증 하지 않은 사용자에게도 Role을 부여 할 수 있게 되었다. 역할기반 인증을 할때 깔끔하다..함 써보라..
10publicoverrideProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, outint totalRecords);
11publicoverrideProfileInfoCollection FindProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, outint totalRecords);
12publicoverrideProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, outint totalRecords);
13publicoverrideProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, outint totalRecords);
/// <summary>
/// CustomSqlMembershipProvider Ver 2.2
/// </summary>
/// <remarks>
/// 06.04.03 - Prototype - 방실
/// 06.07.07 - UserId라는 GUID키를 추가 - 방실
/// 06.07.27 - partial 키워드로 override 부분과 재정의 부분을 분리 - 방실
/// 06.10.13 - GetExceptionText에 case 8: 추가 - 방실
/// 06.10.16 - ChangePassword 메서드의 버그 수정 - 방실
/// </remarks>
참고로 주석을 보면 알겠지만.
처음에 이 프로바이더를 만들었을때는 UserId 항목을 만들지 않았었다.
프로필이라든지 웹파츠를 전혀 쓸 계획이 없었기 때문이다..@.@
(사실 지금도 웹파츠는 실무에서 써본 적이 없다...프로필은 애용하고 있다 ㅋ.)
추가로 프로필에 대해 조금 알게 된 후 프로필프로바이더를 구현 하면서 UserId 부분을 추가 하게 되었다.
앞에 CustomSqlRoleProvider 클래스를 설명할때에도 잠깐 언급을 하였지만.
프로젝트에 따라 테이블 스키마가 매우 다를것이다.
이것을 범용적으로 만들기는 사실상 불가능 하다.
그래서 고민한게 이런 패턴(?)을 생각해 낸건데..
불필요하다고 생각된 컬럼은 제거 하고 확장성을 부여 한것이다.
실제 프로젝트에 들어 가게 되면 기본 테이블 스키마에 프로젝트에 따라 필요한 컬럼들을 추가하고
그에 대한 프로시저를 원본 스키마와 구분하기 위해서 Custom이라는 미들네임을 부여 하여 메서드를 재정의 하는 방향으로 구현 하였다.
쉽게 이르자면.
회원 가입의 경우 CreateUser라는 메서드를 호출한다.
정의된 것과 실제 사용할 테이블 스키마가 다르기 때문에 CreateUser메서드를 재정의 한다.
이때 이 코드는 CustomSqlMembershipProvider에 구현하도록 한다..
아래는 그 예시이다.
[CreateUser]
/// <summary>
/// 속성 값이 지정되고 고유한 식별자를 가진 새 사용자를 데이터 저장소에 추가하고 사용자가 만들어졌음을 나타내거나 사용자 만들기에 실패한 이유를 나타내는 상태 매개 변수를 반환합니다.
/// </summary>
/// <param name="userName">새 사용자의 사용자 아이디입니다.</param>
/// <param name="password">새 사용자의 암호입니다.</param>
/// <param name="password">새 사용자의 이름입니다.</param>
/// <param name="email">새 사용자의 전자 메일 주소입니다.</param>
/// <param name="passwordQuestion">멤버 자격 사용자의 암호 질문 값입니다.</param>
/// <param name="passwordAnswer">멤버 자격 사용자의 암호 대답 값입니다.</param>
/// <param name="isApproved">새 사용자에 대한 로그온이 승인되는지 여부를 나타내는 부울 값입니다.</param>
/// <param name="providerUserKey">멤버 자격 정보 저장소에 저장되어야 하는 사용자 ID입니다.</param>
/// <param name="status">사용자가 만들어졌음을 나타내거나 사용자 만들기에 실패한 이유를 나타내는 MembershipCreateStatus입니다.</param>
/// <returns>새로 만든 사용자에 대한 MembershipUser 개체입니다. 사용자가 만들어지지 않았으면 이 메서드가 Null 참조를 반환합니다. </returns>
public MembershipUser CreateUser(string userName, string password, string realName, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
string encryptPassword ="";
string encryptPasswordAnswer ="";
if (!this.CreateUserValidate(userName, password, email, passwordQuestion, passwordAnswer, isApproved, out status, out encryptPassword, out encryptPasswordAnswer))
{
returnnull;
}
SqlDB db =new SqlDB(this.connectionString);
DateTime time1 = DateTime.Now;
SqlParameter[] param = {
new SqlParameter("@ReturnValue", SqlDbType.Int),
new SqlParameter("@UserId", SqlDbType.UniqueIdentifier),
new SqlParameter("@UserName", SqlDbType.VarChar, 64),
new SqlParameter("@Password", SqlDbType.VarChar, 256),
new SqlParameter("@RealName", SqlDbType.VarChar, 128),
new SqlParameter("@Email", SqlDbType.VarChar, 256),
new SqlParameter("@PasswordQuestion", SqlDbType.VarChar,256),
new SqlParameter("@PasswordAnswer", SqlDbType.VarChar,256),
new SqlParameter("@IsApproved", SqlDbType.Bit),
new SqlParameter("@UniqueEmail", SqlDbType.Bit),
new SqlParameter("@CurrentTime", SqlDbType.DateTime)
};
param[0].Direction = ParameterDirection.ReturnValue;
param[1].Direction = ParameterDirection.InputOutput;
db.ExecuteNonQuery(false, CommandType.StoredProcedure, "dbo.Accounts_Custom_Membership_CreateUser", param, providerUserKey, userName, encryptPassword, realName, email, passwordQuestion, encryptPasswordAnswer, isApproved ? 1 : 0, this.RequiresUniqueEmail ? 1 : 0, time1);
int num3 = db.GetReturnValue<int>(param[0]);
if ((num3 < 0) || (num3 > 11))
{
num3 = 11;
}
status = (MembershipCreateStatus)num3;
if (num3 != 0)
{
returnnull;
}
providerUserKey =new Guid(param[1].Value.ToString());
time1 = time1.ToLocalTime();
returnnew MembershipUser(this.Name, userName, providerUserKey, email, passwordQuestion, null, isApproved, false, time1, time1, time1, time1, new DateTime(0x6da, 1, 1));
}
코드를 보면 알겠지만.
정의된 CreateUser메서드와 상당히 유사하다.
그러나 파라메터가 몇개 추가 되었다..
사용자 정의가 사실 이런게 장점이 아닐까 생각 한다.
프로젝트에 따라서 나름대로 꽤 코드를 많이 생성해야 하지만.
사실 프로젝트라는게 거의 비슷비슷해서 실상은 그리 많은 코드들을 새로 생성하지는 않는다..
클래스 이름은 CustomSqlRoleProvider이다.
이는 MSSQL에서만 통용된다고 먼저 밝힌다.
클래스 이름은 CustomSqlRoleProvider인데 파일 이름은 SqlRoleProvider이다.
앞서 게시글에서도 말했듯이 이 클래스 재정의 패턴은
기존 클래스인 SqlRoleProvider의 기능을 모두(?) 구현하며 확장을 할 수 있게끔 하는 것이다.
그러므로 기존의 SqlRoleProvider의 기능들은 모두 SqlRoleProvider라는 파일에 정의 되어 있고
프로젝트마다 확장되어 변경되어야 하는 부분은 CustomSqlRoleProvider 파일에 있다.
이 두개의 파일은 당연히 Partial로 연결되어져 있으며
이렇게 나눈 이유는
단지 관리상의 편의성 때문이다.
어떤 프로젝트를 하든지간에 SqlRoleProvider파일은 건들 필요가 없으며 CustomSqlRoleProvider파일만 재정의 하면 되기 때문이다.
이부분은 MembershipProvider와도 동일한 패턴이다.
자 먼저 클래스의 주석을 보도록 하자.
[주석]
/// <summary>
/// CustomSqlRoleProvider Ver 2.0
/// </summary>
/// <remarks>06.03.28 - Prototype - 방실</remarks>
/// <remarks>06.07.07 - UserId라는 GUID키를 추가 - 방실</remarks>
/// <remarks>06.07.27 - partial 키워드로 override 부분과 재정의 부분을 분리 - 방실</remarks>
이 클래스는 RoleProvider를 상속 받았다.
이 클래스는 사이트에서 회원(멤버)들을 역할을 이용해서 관리를 하기 위함이다.