Инверсия управления, инъекция зависимостей с SRP и отложенная загрузка - PullRequest
3 голосов
/ 12 января 2010

Мы с одним разработчиком обсуждаем (мягко говоря) ленивую загрузку свойств объекта.

  • Он говорит использовать статический вызов поиска IoC для разрешения и отложенной загрузки объектов объекта.
  • Я говорю, что нарушает SRP, и использует собственный сервис для разрешения этого объекта.

Итак, как бы вы справились с отложенной загрузкой после IoC и SRP?

Вы не можете выполнить модульное тестирование этого свойства с отложенной загрузкой. Он опровергает тот, который говорит: «У вас уже есть модульные тесты для UserStatsService - там есть покрытие кода». Действительная точка, но свойство остается непроверенным для «полного» покрытия.

Настройка / шаблоны кодов:

  • В проекте используются строгие правила внедрения зависимостей (внедряются в каталогах всех служб, репозиториев и т. Д.).
  • Проект использует IoC через Касл (но может быть что угодно, как Unity).

Пример ниже.

public class User
{
  public Guid UserId { get; set; }

  private UserStats _userStats;
  // lazy-loading of an object on an object
  public UserStats UserStats
  {
    get
    {
      if (_userStats == null)
      {
        // ComponentsLookup is just a wrapper around IoC 
        // Castle/Unity/etc.
        _userStats = 
          ComponentsLookup
            .Fetch<UserStatsService>()
              .GetByUserId(this.UserId);
      }
      return _userStats;
    }
  }
}

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

РЕДАКТИРОВАТЬ: Один ответ ниже напомнил мне трюк NHibernate с ленивой загрузкой, которая заключается в виртуализации вашего свойства, позволяя NHibernate создать перегрузку самой ленивой загрузки. Отлично, но мы не используем NHibernate.

Никто на самом деле не занимается вопросом Ленивой загрузки. Некоторые хорошие статьи и ТАК вопросы близки:

Я вижу преимущество ленивой загрузки. Не поймите меня неправильно, все, что я делал, это ленивая загрузка моих сложных типов и их подтипов, пока я не переключился на D.I.-способы ниндзя. Преимущество в уровне пользовательского интерфейса, где статистика пользователя отображается, скажем, в списке из 100 строк. Но с DI теперь вы должны ссылаться на несколько строк кода, чтобы получить статистику этого пользователя (чтобы не нарушать SRP и не нарушать закон Деметры), и он должен пройти этот длинный путь поисков более 100 раз.

Да, да, добавление кэширования и обеспечение того, что UserStatsService закодирован для использования в качестве шаблона Singleton, значительно снижает затраты на производительность.

Но мне интересно, есть ли у кого-нибудь еще [упрямый] разработчик, который просто не будет склоняться к IoC и D.I. правила полностью, и имеет действительные точки производительности / кодирования, чтобы оправдать обходные пути.

1 Ответ

5 голосов
/ 12 января 2010

Сами сущности не должны нести ответственность за ленивую загрузку. Это инфраструктурная проблема, решение которой будет лежать в другом месте.

Скажем, сущность используется в двух разных контекстах. Во-первых, его дети используются интенсивно и загружены. Во втором они используются редко и загружаются ленивыми. Это также проблема организации? Как будет выглядеть конфигурация?

NHibernate отвечает на эти вопросы, передавая тип сущности. Свойство типа IList<Entity> устанавливается инфраструктурой для реализации, которая знает о отложенной загрузке. Сущность остается в блаженном неведении. Родительские ссылки (как в вашем вопросе) также обрабатываются, требуя только простого свойства.

Теперь, когда проблема находится за пределами сущности, инфраструктура (ORM) отвечает за определение контекста и конфигурации (например, нетерпеливая / отложенная загрузка).

...