Различные версии одного и того же типа объекта (любой ORM) для разных ролей / уровней авторизации - PullRequest
1 голос
/ 02 февраля 2010

Рассмотрим, например:

public interface IStaff
{
    FullName name { get; set; }
    EMailAddress email_address { get; set; }
    SocialInsuranceId ssn { get; set; }
    PositiveInt age { get; set; }
    Address home_address { get; set; }
}

Для некоторых пользователей для модели представления требуются только name и email_address. Другие могут иметь модель представления, которая включает эти свойства плюс ssn, age и home_address. Допустим, есть еще статистика, чье мнение получает age и home_address.

Теперь я могу разделить это на IStaffBasic, IStaffDetails и IStaffStats с наследованием интерфейса, чтобы ограничить API в данной модели представления соответствующими свойствами.

Однако, когда этот объект извлекается из службы данных через провод, он все равно будет содержать дополнительные сведения, которые не должны появляться.

Так что, было бы лучше
(A) создать совершенно разные типы объектов для каждой из этих версий, несколько загрязняя API уровня обслуживания множеством дополнительных почти дублирующих операций запроса для каждого типа, или
(B) всегда возвращают объект Staff, но (1) возвращают их из службы с исключенными свойствами, установленными на null, на основе проверки авторизации в службе и (2) используют ограниченные интерфейсы в моделях представления, как описано выше, или
(C) используйте очень элегантный шаблон или решение, которое я не рассматривал, но о котором вы собираетесь мне рассказать.

Вариант A выглядит чище на уровне viewmodel, но API сервиса будет неприятным. Вариант B, по-видимому, добавляет сложности к обработке сущностей на сервере, но лучше придерживается принципа открытого-закрытого.

Мысли

1 Ответ

1 голос
/ 02 февраля 2010

Проекция - путь - объедините варианты A и B.

Ваш ORM должен взаимодействовать только с одним типом сущности, Staff, поэтому вам нужно только поддерживать (и расширять) один набор отображений, запросов и т. Д.

Однако вы также создадите разные классы, подходящие для каждого сценария безопасности (IStaffBasic, IStaffDetails и т. Д.), Спроецируйте на них экземпляры Staff и верните спроецированные объекты по проводу: *

Некоторые ORM поддерживают проекцию как элемент инфраструктуры, но при необходимости вы можете сделать это вручную на уровне обслуживания.

...