2017-10-31 16 views
-2

this accepted answerを使用して列挙型の列挙型を作成しました。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は、列挙型の一部であるかどうかを確認してみてください、それがユーザID = 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文を避けたいので、enumとして使用すると再利用可能になります。

+3

属性を列挙型に追加しても、その列挙型に有効な値は変更されません。 'Guid'値は' IsDefined() 'メソッドでは無効です。なぜそれがうまくいくと思いましたか?実際に何をしようとしていますか?あなたの質問を修正して、文脈がはっきりしている良い[mcve]と、具体的には理解できないことの良い説明が含まれているようにしてください。 –

+0

'2ED3164-BB48-499B-86C4-A2B1114BF1'は有効な' GUID'ではなく '3'文字列がなく、最初の8文字に' 1'が、最後に '2'文字がありません。 – 12seconds

+0

特定のuserIdがAccessRolesに存在する3つのGuidの一部であるかどうかをチェックしたいと思います。したがって、リンクの例を使用してGuidで列挙型を設計し、それが存在するかどうかを調べます。 –

答えて

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にそれらのいくつかの実装があります。

鉱山は、.NETコアv2のためである - Nugetとhttps://github.com/microknights/Collections :インストール・パッケージのMicroKnights.Collections

Headspring - 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); 
    } 
} 

これで、静的なコンストラクタのリストに設定ファイルのデータベースが設定されている方法を変更するだけで済みます。 AccessRolesには、どちらのプロパティでもロールの検索を取得するための静的メソッドが用意されています。それは述語を得る単一のメソッドに置き換えることができますが、私はそれがより読みやすくなると思います。