мои классы POCO должны общаться с репозиториями, и если да, то как это сделать? - PullRequest
3 голосов
/ 29 мая 2011

Я пишу приложение веб-формы ASP.Net с использованием nHibernate. В настоящее время я не использую никаких IoC-фреймворков.

Во-первых - мои сценарии:

  1. Я не хочу допускать двух сотрудников с одинаковыми именами. Я хотел бы включить класс Employee для поиска другого сотрудника с тем же именем и выдать ошибку.

  2. Департамент может иметь 1000 сотрудников. Мне нужно точно знать, сколько сотрудников в каждом департаменте. Я не хочу загружать их все в память, поэтому я использую вычисляемое свойство EmployeesCount. Однако это свойство инициализируется при первой загрузке объекта Department. Если я добавляю / удаляю сотрудников, изменения не отражаются в этом свойстве. (тем более что я использую кэш 2-го уровня, поэтому мой объект сохраняется в нескольких областях Session)

Моя идея решения этих проблем состоит в том, чтобы мои доменные объекты содержали ссылку на соответствующие объекты репозитория.
Я думаю, что наилучшее решение состоит в том, чтобы мои репозитории реализовывали интерфейсы и использовали какой-то механизм контейнера IoC / DI.

Итак, в Employee у меня будет:

if (_empRepository.GetEmployeeByName(newEmployeeName) != null) //...

и в отделе:

public int EmployeesCount
  {
    get
      {
         return _departmentRepository.GetCurrentEmployeesCount(this);
      }
  }

мои вопросы:

  1. Что предпочтительнее - ctor DI

    публичный сотрудник (хранилище IEmployeeRepository)

или с помощью контейнера IoC?

public Employee()
  {
     _empRepository = container.Resolve<IEmployeeRepository>();
  }
  1. Как реализовать желаемое решение? Я понимаю, что Interceptors / Tuplizer - это путь, но я не мог полностью разобраться во всем этом. это хороший пример? Кроме того, в каком пространстве имен я должен определить интерфейсы, контейнер IoC и т. Д.?

Ответы [ 3 ]

4 голосов
/ 29 мая 2011

Отношение POC0-к-персистентности обычно является однонаправленным: уровень постоянства знает о POCO, но не наоборот.

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

Поместить эту деятельность в POCO может показаться хорошей идеей, потому что это помогает избежать ярлыка "модель анемичной области", но я бы не стал этого делать. Я бы поместил эти методы в интерфейсы персистентности и позволил им справиться с этим. Также более вероятно, что служба, отвечающая за выполнение варианта использования, захочет узнать дубликаты имен сотрудников; пусть он попросит и оставит POCO вне разговора.

Такой подход облегчит вам тестирование. Вы узнаете, насколько болезненными могут быть циклы модулей, когда пойдете на тестирование. Вам придется затянуть слишком много техники в тест, чтобы заставить его работать.

3 голосов
/ 30 мая 2011

Я также думаю, что Покос не должен знать о стойкости.Рассматривали ли вы альтернативы, такие как

class Department
{
    public int Id { get; set; }
    public IList<Employee> ActiveEmployees { get; set; }
}

public DepartmentMap()
{
    ...
    HasMany(d => d.ActiveEmployees)
        .KeyColumn("department_id")
        .Where("stillactiveindepartment = true")      // for example
        .ExtraLazyLoad();  // will issue an Count(*) instead of initializing collection, also other methods like Contains() issue an sql
}

Для сотрудника с уникальными именами:

1) в сервисе / контроллере: перед сохранением нового сотрудника выполните запрос, который проверяет, является ли сотрудник с тем же именемуже существует.

2) Уникальное ограничение в базе данных даст исключение при сохранении.

3) Пользовательский перехватчик в сеансе, который перехватывает событие сохранения / сброса.может бросить, если уже есть клиент

1 голос
/ 29 мая 2011

Другой ответ в основном касается вопросов, которые вы задавали, и я согласен с советом там.

Если у вас есть вопрос о доступе к количеству сотрудников, ознакомьтесь с использованием прогнозов в NHibernate. Я бы поместил запрос на уровень вашего сервиса (для какой-либо операции веб-сервиса, чтобы получить количество сотрудников), который использует прогноз количества.

РЕДАКТИРОВАТЬ: Забыл, что вы используете Услуги / Репозитории / POCO. В этом случае создайте запрос подсчета сотрудников в хранилище и вызовите его из службы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...