Эмулирующий тип значения Полиморфизм в C Sharp

2

Я ищу способ создания иерархической структуры классов типа значений. Я знаю, что перечисления не поддерживают наследование, поскольку они являются типами значений и поэтому запечатаны, поэтому я, вероятно, ищу какую-то статическую реализацию класса.

Моя цель - переопределить роли в этом приложении ASP.NET, над которым я работаю. В настоящее время роли представляют собой строковые константы (ROLE_ADMIN, ROLE_USER и т.д.) И помещаются в сеанс и проверяются по всему приложению примерно так: Person.getRole() == ROLE_ADMIN (это фактически сравнение строк). Я бы хотел реорганизовать это, чтобы у меня была безопасность типа, а также какое-то полиморфное поведение, как описано ниже.

Рассмотрим следующую структуру ролей:

             user1
      Group1
             user2
Admin
      User3

Если роль человека установлена ​​в Group1, но определенный элемент на странице отображается только пользователем1, тогда я хочу, чтобы выражение Person.getRole() == user1 было истинным.

EDIT:

Размышляя о структуре в качестве дерева, я хотел бы иметь возможность определить пользователя в терминах листа или node и проверить разрешения в терминах листа или node. Однако это порождает дилемму, проверяет ли разрешения в терминах node проверку, принадлежит ли пользователь группе (group1), или IS - группе (Admin). Я считаю, что проблема в том, что имя корня node моего дерева как "Admin" вводит в заблуждение, поскольку узлы должны рассматриваться как группы, а не сами роли. Корень node должен быть чем-то вроде "Все", и когда он определяется как "Все", он наследует все листья дерева и поэтому будет принадлежать всем группам.

  • 0
    Я собираюсь сократить свои потери и пока оставлю этот вопрос. Для дальнейшего использования я отметил ответ, который мне показался наиболее подходящим. К сожалению, для этого изменения не было никаких деловых причин, и для его завершения требуется слишком много времени.
Теги:

3 ответа

1
Лучший ответ

Я не уверен, какие типы значений имеют отношение к этому (строка является ссылочным типом). Общим подходом здесь является использование IPrincipal.IsInRole или что-то подобное.

Ваша "иерархическая" проблема переместится на ту часть, где заполняются роли.

  • 0
    Я предполагаю, что искал объекты, которые не изменяют состояние и просто представляют «значение», поэтому я связал это с типами значений. Кто-то еще упомянул неизменные объекты, о которых я забыл. Я не знал о структуре Принципала и Идентичности, встроенной в .NET, и я рассмотрю ее.
  • 0
    Само по себе это решение не реализует безопасность типов, поэтому мне пришлось бы рассмотреть варианты обертывания системы принципала / идентификации для использования перечислений. Я знаю, что есть методы для преобразования строк и перечислений туда и обратно. Я также хотел бы обернуть его таким образом, чтобы мне не приходилось выполнять проверки, такие как Principal.IsInRole ('user1') || Principal.IsInRole ('user2'), чтобы определить, находятся ли они в group1.
Показать ещё 1 комментарий
0

Угадай, что пользователь должен войти в систему? Поэтому, когда они регистрируются, почему вы не добавляете объект пользователя в сеанс?

// Object to represent a user
public class SiteUser
{
    public String Name { get; set; }
    public UserTypes UserType { get; set; }
}

// Enumeration of user types
public enum UserTypes : int
{
    Admin = 1,
    General = 2
}

public partial class Home : System.Web.UI.Page 
{    
    private void Login()
    {
        // Login method here, take username password etc...
        // This is for example purposes...
        SiteUser user = new SiteUser();

        user.UserType = UserTypes.Admin;
        user.Name = "Bob";

        Session["User"] = user;
    }
}

public partial class AdminOnlyPage : System.Web.UI.Page 
{    
    private void Page_Load(object sender, EventArgs e)
    {
        // On pages where we want to know the user details
        // cast the session user object back to our SiteUser object.
        SiteUser user = Session["User"] as SiteUser;

        // This page is admin only, if our user in session isn't an admin
        // then redirect them else where...
        if (user.UserType != UserTypes.Admin)
        {
            Response.Redirect("/LoginPage.aspx");
        }
    }
}
  • 0
    Извините, я не указал, пользователям не нужно входить в систему, есть веб-служба, которая передает учетные данные, и приложение переводит это состояние в сеанс. Это решение решает проблему безопасности типов с помощью перечисления, но иерархическая проблема все еще не решена. Я бы хотел не определять ADMIN как собственную роль, а скорее объединять другие роли. Ссылаясь на мой пример, я проверю код только на роли, которые являются листьями в дереве, и узлы в дереве будут разрешены на основе того, какие роли содержатся в виде листьев в их поддереве.
0

Один из способов эмулировать семантику значения типа с объектами - это неизменные объекты. Если это незнакомая концепция, то короткая версия: "После того, как они были построены, они не меняют состояние", которые не являются сеттерами, не являются публичными полями (но кто будет делать такую ​​глупость любыми способами; p) и никакими методами с побочными эффектами.

Эрик Липперт написал очень хорошую серию статей о концепции неизменности: неизменяемость первая часть

  • 0
    Я забыл о неизменных объектах. Я буду смотреть на это дальше.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню