2017-10-31 22 views
-2

this accepted answer을 사용하여 Guid 열거 형을 생성했습니다.GUID 열거 형 만들기

public enum AccessRoles 
{ 
    [EnumGuid("2ED3164-BB48-499B-86C4-A2B1114BF1")] 
    SysAdmin =1, 
    [EnumGuid("A5690E7-1111-4AFB-B44D-1DF3AD66D435")] 
    Admin = 2, 
    [EnumGuid("30558C7-66D9-4189-9BD9-2B87D11190")] 
    OrgAdmin = 3, 
} 

class EnumGuid : Attribute 
{ 
    public Guid Guid; 

    public EnumGuid(string guid) 
    { 
     Guid = new Guid(guid); 
    } 
} 

나는 GUID를 열거의 일부가 있는지 확인하십시오, 그것은 userId를 = 2ED3164-BB48-499B-86C4-A2B1114BF1가 유효한 GUID 경우에도 예외 System.InvalidOperationException 발생합니다.

if(Enum.IsDefined(typeof(AccessRoles), userId)) 
{ 

}  

문자열로 변환하고 확인하려고했지만 오류가 발생하지 않지만 if 루프 내부로 들어 가지 않았습니다.

if(Enum.IsDefined(typeof(AccessRoles), userId.ToString().ToUpper())) 
{ 

} 

그래서 어떻게 수정합니까? 아니면 더 좋은 방법이 있습니까? 여러 if 문이나 case 문을 피하기 위해 열거 형으로 사용하여 재사용 할 수 있도록하고 싶습니다.

+3

열거 형에 특성을 추가해도 해당 열거 형에 유효한 값은 변경되지 않습니다. 'Guid' 값은'IsDefined()'메소드에 유효하지 않습니다. 왜 그것이 효과가 있다고 생각 했습니까? 당신은 실제로 무엇을하려고합니까? 질문을 수정하여 문맥을 분명히 보여주는 좋은 [mcve]와 구체적으로 파악할 수없는 것에 대한 좋은 설명을 포함 시키십시오. –

+0

'2ED3164-BB48-499B-86C4-A2B1114BF1'은 유효한 GUID가 아니므로'3' 문자가 누락되었습니다. 처음 8 개는 '1'이고 마지막 부분은'2 '입니다. – 12seconds

+0

특정 userId가 AccessRoles에있는 3 Guids에 속하는지 확인하고 싶습니다. 따라서 링크의 예제를 사용하여 Guids가있는 열거 형을 디자인하고 존재하는지 확인하십시오. –

답변

1

고정 된 사용자 역할로 작업 할 때 완전히 다른 접근 방식을 제안합니다. 당신이 동일한 달성하고 훨씬 더 할 수있는 열거를 사용

: 추상 UserRoleType 가상/추상적 인 속성을 설정하여

public abstract class UserRoleType : Enumeration<UserRoleType> 
{ 
    protected UserRoleType(int value, string displayName) 
     : base(value, displayName) 
    {} 

    public static readonly UserRoleType Unknown = new UnknownRoleType(); 
    public static readonly UserRoleType Administrator = new AdministratorRoleType(); 
    public static readonly UserRoleType System = new SystemRoleType(); 
    public static readonly UserRoleType Moderator = new ModeratorRoleType(); 

    public virtual bool CanCreateUser => false; 
    public virtual bool CanBlockUser => false; 
    public virtual bool CanResetUserPassword => false; 
} 

public sealed class UnknownRoleType : UserRoleType 
{ 
    public UnknownRoleType() 
     : base(0, "Unknown") 
    { } 
} 

public sealed class AdministratorRoleType : UserRoleType 
{ 
    public AdministratorRoleType() 
     : base(10, "Administrator") 
    {} 

    public override bool CanCreateUser => true; 
    public override bool CanBlockUser => true; 
    public override bool CanResetUserPassword => true; 
} 

public sealed class SystemRoleType : UserRoleType 
{ 
    public SystemRoleType() 
     : base(20, "System") 
    { } 
    public override bool CanBlockUser => true; 
    public override bool CanResetUserPassword => true; 
} 

public sealed class ModeratorRoleType : UserRoleType 
{ 
    public ModeratorRoleType() 
     : base(40, "Moderator") 
    { } 
    public override bool CanBlockUser => true; 
} 

, 당신 시스템은 추상 클래스에서 작동합니다. 사용자 컨텍스트 (로그인에) 초기화되고

, 당신은 단순히 열거 클래스에 대한

 var roleTypeValueFromDatabase = 10; 
     var roleType = UserRoleType.FromValueOrDefault(roleTypeValueFromDatabase, UserRoleType.Unknown); 

     if (roleType.CanCreateUser) 
     { 
      // create user.. 
     } 

     // Find roles with specific rights 
     var rolesThatCanResetPassword = UserRoleType.GetAll().Where(urt => urt.CanResetUserPassword); 

하여 사용자의 역할을 찾아, GitHub의/nuget에 그들의 여러 구현이 있습니다.

내 닷넷 코어 V2입니다 - Nuget와 https://github.com/microknights/Collections : 설치 - 패키지 MicroKnights.Collections

수원 - https://github.com/HeadspringLabs/Enumeration 소스 파일 만.

나는 불변의 구조체와 열거를 교체하고 응용 프로그램의 모든 가능한 역할을 유지하는 정적 클래스를 추가
+0

수백 가지 유형이있는 대신 몇 가지 필드와 해당 필드를 기반으로 적절한 값을 반환하는 단일 유형을 사용할 수 있습니다. – Servy

+0

정답을 할 수는 있지만 개인적으로 특정 구현을 선호합니다. –

1

:

public struct AccessRole 
{ 
    public AccessRole(Guid guid, int number, string name) : this() 
    { 
     Uuid = guid; 
     Number = number; 
     Name = name; 
    } 

    public Guid Uuid {get;} 
    public int Number {get;} 
    public string Name {get;} 
} 

는 그런 다음 AccessRoles을 위해 정적 클래스를 추가 할 수 있습니다

public static class AccessRoles 
{ 
    private static List<AccessRole> _roles; 
    static AccessRoles() 
    { 
     _roles = new List<AccessRole>(); 
     // Here I populate it hard coded for the sample, 
     // but it should be populated from your database or config file 
     _roles.Add(new AccessRole(new Guid("2ED3164-BB48-499B-86C4-A2B1114BF1"), 1, "SysAdmin")); 
     _roles.Add(new AccessRole(new Guid("A5690E7-1111-4AFB-B44D-1DF3AD66D435"), 2, "Admin")); 
     _roles.Add(new AccessRole(new Guid("30558C7-66D9-4189-9BD9-2B87D11190"), 3, "OrgAdmin")); 
    } 

    public static AccessRole GetRole(Guid uuid) 
    { 
     return _roles.Find(r => r.Uuid == uuid); 
    } 

    public static AccessRole GetRole(int number) 
    { 
     return _roles.Find(r => r.Number == number); 
    } 

    public static AccessRole GetRole(string name) 
    { 
     return _roles.Find(r => r.Name == name); 
    } 
} 

이제 고정 구성 자에서 _roles 목록이 구성 파일의 데이터베이스로 채워지는 방식을 변경하면됩니다. AccessRoles는 두 가지 속성 중 하나를 통해 역할 검색을 가져 오는 정적 메서드를 제공합니다. 그것은 술어를 얻을 수있는 하나의 메소드로 대체 될 수 있지만, 나는 이것이 더 읽기 쉽다고 생각한다.