Статический метод как часть контракта - PullRequest
4 голосов
/ 10 октября 2011

Я внедряю инфраструктуру для контроля доступа моделей в веб-приложении.В библиотеке есть класс контекста, который контроллеры (и, возможно, представления) используют для определения, имеет ли текущий пользователь доступ к определенному объекту.Для сохранения соответствующей информации вблизи целевого объекта я решил передать запрос проверки доступа самим моделям из объекта контекста.

Реализация этого механизма для модификации объекта модели является почти тривиальной.Объявите интерфейс, скажем, ICheckModifyAccess;и реализовать его в вашей модели.То же самое касается проверки удаления.В обоих этих случаях можно спросить экземпляр модели, можно ли их изменить или удалить.

К сожалению, это не относится к операциям чтения и создания.Эти операции требуют, чтобы я задал вопрос модели класс .Поэтому использование интерфейса для этого не вариант.

В итоге я создал атрибут CheckCreateAccessAttribute, а затем использовал этот атрибут для пометки статической функции в качестве функции интерфейса.Затем в моем объекте контекста я могу использовать отражение, чтобы проверить, существует ли такая помеченная функция, соответствует ли она ожидаемой сигнатуре, и в конце концов вызвать ее.В случае, если это имеет значение, метод для создания проверки доступа - public bool CanCreate<TObj>();.Типичная модель, которая поддерживает управление доступом, добавила бы в класс что-то вроде следующего:

[CheckCreateAccess]
public static bool CanCreate()
{
    return true;
}

Я пока не очень хорошо говорю на C #, и у меня появляется ноющее чувство, что я делаю что-то не так.Можете ли вы предложить более элегантную альтернативу?Особенно, вы можете избавиться от изучения TObj отражением?

Ответы [ 2 ]

2 голосов
/ 10 октября 2011

Звучит так, как будто вы объединили проблемы в своих классах объектов вместо , разделяющих их .

Искушение "держать релевантную информацию рядом с целевым объектом", возможно, привело вас к этой структуре.

Возможно, вы могли бы вместо этого обрабатывать разрешения в отдельном классе, см., Например, эту статью .

2 голосов
/ 10 октября 2011

Я думаю, вам не следует спрашивать какого-то конкретного пользователя, можете ли вы изменить его (если только право на изменение не относится к конкретной сущности). Просто создайте класс, который обрабатывает права (или используйте соответствующий существующий класс).

Это избавит вас от необходимости использовать статические классы и рефлексию.

Если у вас будет много типов, с настраиваемыми правилами (то есть кодом) для каждого из них, вы можете иметь общий абстрактный тип (интерфейс или абстрактный класс), который может проверять правила для одного типа и некоторый репозиторий для извлечения конкретного экземпляра.

...