创建一个GUID枚举

时间:2017-10-31 20:45:48

标签: c# enums guid

我使用this accepted answer创建了一个Guum的枚举。

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是否是枚举的一部分,它会抛出异常System.InvalidOperationException,即使userId = 2ED3164-BB48-499B-86C4-A2B1114BF1是有效的guid。

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

}    

我尝试将其转换为字符串并进行检查,但那次它不会引发错误但不会进入if循环。

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

} 

那我该如何解决呢?或者,还有更好的方法?我想避免使用多个if语句或case语句,以及如何将它作为枚举使用,以便它们可以重用。

3 个答案:

答案 0 :(得分:2)

在使用固定用户角色时,我建议采用完全不同的方法。

使用枚举可以实现相同甚至更多:

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

通过在抽象UserRoleType上设置抽象/虚拟属性,系统只对抽象类进行操作。

初始化用户上下文时(登录时),您只需通过

找到用户角色
        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);

关于Enumeration类,github / nuget上有几个实现。

我的是.Net核心v2 - https://github.com/microknights/Collections 使用Nuget:Install-Package MicroKnights.Collections

Headspring - https://github.com/HeadspringLabs/Enumeration 仅限源文件。

答案 1 :(得分:2)

我会用不可变结构替换你的枚举,并添加一个静态类来保存应用程序中所有可能的角色:

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提供静态方法以通过任一属性搜索角色。它可以用一个可以获得谓词的方法替换,但我认为这种方式更具可读性。

答案 2 :(得分:2)

public enum AccessRoles
{
    SysAdmin = 1,
    Admin = 2,
    OrgAdmin = 3
}


public class Attributes
{
    public static Dictionary<int, Guid> Attribute = new Dictionary<int, Guid>()
    {
        {(int)AccessRoles.SysAdmin, Guid.Parse("6D18698C-04EC-4E50-84DB-BE513D5875AC")},
        {(int)AccessRoles.Admin, Guid.Parse("32E86718-7034-4640-9076-A60B9B6CA51A")},
        {(int)AccessRoles.OrgAdmin, Guid.Parse("2CA39E37-8AEA-463F-AE14-E9D92AC5FB5E")}
    };
}

Console.WriteLine(Attributes.Attribute[(int)AccessRoles.SysAdmin]);
Console.WriteLine(Attributes.Attribute[(int)AccessRoles.Admin]);
Console.WriteLine(Attributes.Attribute[(int)AccessRoles.OrgAdmin]);