87 votes

Que faire quand le masque de bits (drapeaux) devient trop grand

J'ai un très grand ensemble d'autorisations dans mon application que je représente avec un Drapeaux de l'énumération. Il s'approche rapidement de la pratique à la limite supérieure du type de données long. Et je suis obligé de venir avec une stratégie de transition vers une structure différente bientôt. Maintenant, je pourrais diviser cette liste en petits morceaux, cependant, déjà, c'est juste un sous-ensemble de l'ensemble des autorisations pour notre application, basée sur nos applications de mise en page. Nous utilisons cette distinction largement pour l'affichage et la gestion des autorisations et je préfère ne pas avoir à revoir le code à ce moment si je peux l'éviter.

Quelqu'un d'autre a rencontré ce problème? Comment avez-vous passé? Des exemples généraux sont beaux, mais je suis plus intéressée par un c# spécifiques, par exemple si il y a n'importe quelle langue spécifique des trucs que je peux employer pour obtenir le travail fait.

Peut ne pas être nécessaire, mais voici la liste des Autorisations actuellement définis pour la partie de l'application que je fais affaire avec.

//Subgroup WebAgent
[Flags]
public enum WebAgentPermission : long
{
    [DescriptionAttribute("View Rule Group")]
    ViewRuleGroup = 1,
    [DescriptionAttribute("Add Rule Group")]
    AddRuleGroup = 2,
    [DescriptionAttribute("Edit Rule Group")]
    EditRuleGroup = 4,
    [DescriptionAttribute("Delete Rule Group")]
    DeleteRuleGroup = 8,
    [DescriptionAttribute("View Rule")]
    ViewRule = 16,
    [DescriptionAttribute("Add Rule")]
    AddRule = 32,
    [DescriptionAttribute("Edit Rule")]
    EditRule = 64,
    [DescriptionAttribute("Delete Rule")]
    DeleteRule = 128,
    [DescriptionAttribute("View Location")]
    ViewLocation = 256,
    [DescriptionAttribute("Add Location")]
    AddLocation = 512,
    [DescriptionAttribute("Edit Location")]
    EditLocation = 1024,
    [DescriptionAttribute("Delete Location")]
    DeleteLocation = 2048,
    [DescriptionAttribute("View Volume Statistics")]
    ViewVolumeStatistics = 4096,
    [DescriptionAttribute("Edit Volume Statistics")]
    EditVolumeStatistics = 8192,
    [DescriptionAttribute("Upload Volume Statistics")]
    UploadVolumeStatistics = 16384,
    [DescriptionAttribute("View Role")]
    ViewRole = 32768,
    [DescriptionAttribute("Add Role")]
    AddRole = 65536,
    [DescriptionAttribute("Edit Role")]
    EditRole = 131072,
    [DescriptionAttribute("Delete Role")]
    DeleteRole = 262144,
    [DescriptionAttribute("View User")]
    ViewUser = 524288,
    [DescriptionAttribute("Add User")]
    AddUser = 1048576,
    [DescriptionAttribute("Edit User")]
    EditUser = 2097152,
    [DescriptionAttribute("Delete User")]
    DeleteUser = 4194304,
    [DescriptionAttribute("Assign Permissions To User")]
    AssignPermissionsToUser = 8388608,
    [DescriptionAttribute("Change User Password")]
    ChangeUserPassword = 16777216,
    [DescriptionAttribute("View Audit Logs")]
    ViewAuditLogs = 33554432,
    [DescriptionAttribute("View Team")]
    ViewTeam = 67108864,
    [DescriptionAttribute("Add Team")]
    AddTeam = 134217728,
    [DescriptionAttribute("Edit Team")]
    EditTeam = 268435456,
    [DescriptionAttribute("Delete Team")]
    DeleteTeam = 536870912,
    [DescriptionAttribute("View Web Agent Reports")]
    ViewWebAgentReports = 1073741824,
    [DescriptionAttribute("View All Locations")]
    ViewAllLocations = 2147483648,
    [DescriptionAttribute("Access to My Search")]
    AccessToMySearch = 4294967296,
    [DescriptionAttribute("Access to Pespective Search")]
    AccessToPespectiveSearch = 8589934592,
    [DescriptionAttribute("Add Pespective Search")]
    AddPespectiveSearch = 17179869184,
    [DescriptionAttribute("Edit Pespective Search")]
    EditPespectiveSearch = 34359738368,
    [DescriptionAttribute("Delete Pespective Search")]
    DeletePespectiveSearch = 68719476736,
    [DescriptionAttribute("Access to Search")]
    AccessToSearch = 137438953472,
    [DescriptionAttribute("View Form Roles")]
    ViewFormRole = 274877906944,
    [DescriptionAttribute("Add / Edit Form Roles")]
    AddFormRole = 549755813888,
    [DescriptionAttribute("Delete UserFormRolesDifferenceMasks")]
    DeleteFormRole = 1099511627776,
    [DescriptionAttribute("Export Locations")]
    ExportLocations = 2199023255552,
    [DescriptionAttribute("Import Locations")]
    ImportLocations = 4398046511104,
    [DescriptionAttribute("Manage Location Levels")]
    ManageLocationLevels = 8796093022208,
    [DescriptionAttribute("View Job Title")]
    ViewJobTitle = 17592186044416,
    [DescriptionAttribute("Add Job Title")]
    AddJobTitle = 35184372088832,
    [DescriptionAttribute("Edit Job Title")]
    EditJobTitle = 70368744177664,
    [DescriptionAttribute("Delete Job Title")]
    DeleteJobTitle = 140737488355328,
    [DescriptionAttribute("View Dictionary Manager")]
    ViewDictionaryManager = 281474976710656,
    [DescriptionAttribute("Add Dictionary Manager")]
    AddDictionaryManager = 562949953421312,
    [DescriptionAttribute("Edit Dictionary Manager")]
    EditDictionaryManager = 1125899906842624,
    [DescriptionAttribute("Delete Dictionary Manager")]
    DeleteDictionaryManager = 2251799813685248,
    [DescriptionAttribute("View Choice Manager")]
    ViewChoiceManager = 4503599627370496,
    [DescriptionAttribute("Add Choice Manager")]
    AddChoiceManager = 9007199254740992,
    [DescriptionAttribute("Edit Chioce Manager")]
    EditChoiceManager = 18014398509481984,
    [DescriptionAttribute("Delete Choice Manager")]
    DeleteChoiceManager = 36028797018963968,
    [DescriptionAttribute("Import Export Choices")] //57
    ImportExportChoices = 72057594037927936
}

42voto

Fredrik Mörk Points 85694

Je vois des valeurs d'au moins une poignée de différentes énumérations là...

Ma première pensée a été d'aborder le problème en divisant les autorisations en groupes logiques (RuleGroupPermissions, RulePermissions, LocationPermissions, ...) et puis d'avoir une classe (WebAgentPermissions) exposer une propriété pour chaque autorisation de type enum.

Depuis l'autorisation valeurs semblent répétitives, vous pouvez probablement vous en sortir avec une simple enum à la fin:

[Flags]
public enum Permissions
{
    View = 1,
    Add = 2,
    Edit = 4,
    Delete = 8
}

Et puis avoir l' WebAgentPermissions de la classe d'exposer une propriété pour chaque zone où les autorisations sont à définir;

class WebAgentPermissions
{
    public Permissions RuleGroup { get; set; }
    public Permissions Rule{ get; set; }
    public Permissions Location{ get; set; }
    // and so on...
}

27voto

the.jxc Points 1671

Documentation sur le langage dit:

http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx

"Le sous-jacent est de type Int32 et donc le maximum de bit unique drapeau est 1073741824 et, évidemment, il y a un total de 32 drapeaux pour chaque enum."

Cependant... mise à JOUR:

Intervenant est correct. Découvrez ce:

http://msdn.microsoft.com/en-us/library/ms182147(SV.80).aspx

Int32 est seulement le type de données par DÉFAUT! En fait, vous pouvez spécifier Int64.

public enum MyEnumType : Int64

...permettre à un maximum de 64 valeurs. Mais cela semble être le maximum, après que vous allez être à la recherche à la ré-ingénierie. Sans savoir trop sur le reste de votre solution, je ne peux pas dire exactement ce que pourrait convenir. Mais un tableau (ou hash-plan) de privilège identifiants est probablement le plus naturel de l'approche.

14voto

arbiter Points 5503

Vous pouvez vérifier la classe BitArray . Peut-être que vous l'utiliserez à l'avenir.

5voto

mquander Points 32650

En C #, un moyen flexible de représenter une valeur qui est en quelque sorte une énumération, mais plus flexible, consiste à la représenter sous forme de classe statique avec des valeurs précuites disponibles, comme ceci:

 public sealed class WebAgentPermission
{
    private long ID;

    public static readonly WebAgentPermission
        ViewRuleGroup = new WebAgentPermission { ID = 1 };
    public static readonly WebAgentPermission
        AddRuleGroup  = new WebAgentPermission { ID = 2 };

    private WebAgentPermission() { } 

    // considerations: override equals/gethashcode, probably override tostring,
    // maybe implicit cast to/from long, maybe other stuff
}
 

Alternativement, il suffit de séparer la chose; il semblerait que vous puissiez le faire si vous avez vraiment essayé.

4voto

Talljoe Points 8423

Si j'étais dans le contrôle de cette application, je serais probablement venir avec un ensemble commun d'autorisations (Afficher, Ajouter, Modifier, Supprimer, Télécharger/Importation) et un ensemble de ressources (les Utilisateurs, les Rôles, les Règles, etc). Sur la page web trouver le type de ressource associée à cette page, puis de vérifier les autorisations. Peut-être quelque chose comme:

Permissions perms = agent.GetPermissions(ResourceType.User);
if((perms & Permissions.View) == Permissions.View) { /* do work */ }

ou

Permissions perms = agent.Permissions[ResourceType.User];
if((perms & Permissions.View) == Permissions.View) { /* do work */ }

ou même

if(agent.IsAuthorized(ResourceType.User, Permissions.View)) { /* do work */ }

Vous avez un couple d'autorisations qui n'ont pas de sens avec tout le reste (à Affecter Permissoins à l'utilisateur, au nom de l'un). Je ne suis pas sûr de savoir comment je réagirais, basé sur la façon dont je connais le problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X