#c# #interface #static-methods
#c# #интерфейс #статические методы
Вопрос:
Я внедряю инфраструктуру для управления доступом к моделям в веб-приложении. В библиотеке есть класс контекста, который контроллеры (и, возможно, представления) используют для определения, имеет ли текущий пользователь доступ к определенному объекту. Чтобы сохранить соответствующую информацию рядом с целевым объектом, я решил передать запрос проверки доступа к самим моделям из объекта контекста.
Реализация этого механизма для модификации объекта модели почти тривиальна. Объявите интерфейс, скажем, ICheckModifyAccess
; и реализуйте его в своей модели. То же самое касается проверки удаления. В обоих этих случаях можно спросить экземпляр модели, можно ли их изменять или удалять.
К сожалению, это не относится к операциям чтения и создания. Эти операции требуют, чтобы я задал вопрос классу модели. Поэтому использование интерфейса для этого не вариант.
В итоге я создал атрибут CheckCreateAccessAttribute
, а затем использовал этот атрибут для обозначения статической функции как функции интерфейса. Затем в моем объекте контекста я могу использовать отражение, чтобы проверить, существует ли такая отмеченная функция, соответствует ли она ожидаемой сигнатуре, и в конечном итоге вызвать ее. В случае, если это имеет значение, метод проверки доступа к созданию является public bool CanCreate<TObj>();
. Типичная модель, поддерживающая контроль доступа, добавила бы к классу что-то вроде следующего:
[CheckCreateAccess]
public static bool CanCreate()
{
return true;
}
Я еще не очень хорошо владею C #, и у меня есть неприятное чувство, что я делаю что-то не так. Можете ли вы предложить более элегантную альтернативу? В частности, можете ли вы избавиться от проверки TObj
путем отражения?
Комментарии:
1. Я не понимаю. Почему у вас не может быть экземпляра модели для операций создания и чтения?
2. Элегантность, по основной причине. Например, я хочу создать список всех пользователей. Если я помещу его в интерфейс, для проверки доступа на чтение мне нужно будет создать экземпляр фиктивного пользователя, спросить, могу ли я читать с помощью этого экземпляра, а затем продолжить и создать список, если мне разрешено. При вышеупомянутом подходе я спрашиваю, могу ли я читать объекты этого класса, а затем читать их.
Ответ №1:
Похоже, вы объединили проблемы в своих классах объектов вместо того, чтобы разделять их.
Возможно, искушение «хранить соответствующую информацию рядом с целевым объектом» привело вас к этой структуре.
Возможно, вы могли бы вместо этого обрабатывать разрешения в отдельном классе, см., например, эту статью.
Комментарии:
1. Звучит как хороший совет. Может быть, я могу создать универсальный класс, который реализует правила контроля доступа по умолчанию, и специализировать их для каждой из моих моделей (я слишком много думаю о C ?). Или, может быть, я могу просто последовать совету Свика и объединить все правила в одном классе.
2. Хорошая ссылка на статью. Хотел бы я 2. Это поможет организовать использование вещей на контроллерах.
3. Как я и подозревал, специализация шаблонов — это очень похожий на C способ сделать это. Мне нужно будет найти другой способ. В любом случае, разделение проблем было очень хорошим советом. Он удаляет связь между объектами моей модели и этим конкретным приложением и его правилами контроля доступа, позволяя повторно использовать их в других проектах.
Ответ №2:
Я думаю, вам не следует спрашивать какого-то конкретного пользователя, можете ли вы изменить его (если только право изменения не относится к конкретному объекту). Просто создайте класс, который обрабатывает права (или используйте соответствующий существующий класс).
Это избавило бы вас от необходимости в статических классах и отражении.
Если у вас будет много типов с пользовательскими правилами (т. Е. Кодом) для каждого из них, у вас может быть общий абстрактный тип (интерфейс или абстрактный класс), который способен проверять правила для одного типа, и некоторый репозиторий для извлечения конкретного экземпляра.
Комментарии:
1. Это также один из альтернативных подходов, которые мы рассматриваем. Недостатком этого является то, что класс, реализующий правила управления доступом для всех, становится больше по мере добавления большего количества моделей. Плюсом является то, что все просто, красиво и централизовано. Существуют также общие правила, такие как «пользователь может изменять свой собственный пост, но не чужой». Таким образом, ACL для модификации в некоторых случаях включает просмотр внутренней части моделей. Поэтому запрос самой модели выглядит более подходящим.