Вопросы относительно Entity Framework + DDD - PullRequest
3 голосов
/ 07 октября 2009

Мне трудно найти простые примеры использования EF в шаблоне стиля DDD. Я также впервые использую DDD и у меня есть несколько вопросов относительно схемы решения и того, как использовать некоторые шаблоны DDD.

1) Большинство примеров, которые я видел относительно использования шаблона Repository w / EF, просто показывают специализированные интерфейсы модели, такие как IContactRepository, а затем конкретный тип, реализующий интерфейс. В идеале я хотел бы использовать что-то вроде IRepository, которое имеет базовый набор функций для операций CRUD. Затем я мог бы при необходимости создать специализированные репозитории, такие как IContactRepository: IRepository, когда это необходимо, поскольку большинство моих моделей не нужно будет расширять. Я лаю не на том дереве? Может ли кто-нибудь предоставить мне ж / примеры этого стиля реализации?

2) В настоящее время мое решение разбито на следующие три проекта: Модели (содержит мой EDM), Репозитории и Сервисы. Это уместно или есть другой подход к компоновке, который я не рассматриваю и должен быть?

3) Я видел примеры репозиториев, имеющих методы Query (Func ) / Query (), которые возвращают IQueryable. Это вонючий или что-то нахмурилось?

Ответы [ 3 ]

2 голосов
/ 07 октября 2009

В настоящее время мы используем EF с DDD, но я должен сказать, что в его текущей реализации EF не очень подходит для такого рода архитектуры. Основная проблема заключается в том, что единственный способ, которым EF работает в настоящее время, состоит в том, чтобы каждый объект «Entity» происходил из базового класса, специфичного для EF.

С другой стороны, весь смысл репозиториев состоит в том, чтобы абстрагировать от технологии доступа к данным. Вся идея DDD заключается в том, что модель предметной области должна быть неограниченной из-за деталей реализации, таких как выбор технологии доступа к данным. Это означает, что доменные объекты должны быть определены так, чтобы они оставались невежественными.

Другими словами: вы не можете использовать EF 'Entities' в качестве объектов домена, поэтому в вашем DAL вы должны вручную написать много кода, который отображается в и из объектов домена в EF 'Entities'. Это очень быстро устает.

Я бы определенно посчитал наличие IQueryable в репозитории утечкой абстракции, и это не имеет большого смысла на языке DDD. Если доменные объекты являются связными единицами, не имеет особого смысла выбирать из них только определенные «столбцы».

В EF для .NET 4.0 мы получим невосприимчивость к постоянству, поэтому в будущем она должна стать лучше ...

2 голосов
/ 28 декабря 2010

Я бы хотел ответить # 3 ...

Я думаю, что это менее "вонючий" и более "ленивый". Вот типичный «репозиторий», который я видел в интернете ...

public interface IRepository {
  // Query operations.
  IQueryable<T> All<T>();
  IQueryable<T> Find<T>(Expression<Func<T, bool>> expression);
  T Single<T>(Expression<Func<T, bool>> expression);

  // Save operations.
  T Add<T>(T objectToAdd);
  void Delete<T>(T objectToDelete);
  T Update<T>(T objectToUpdate);
}

Насколько я знаю, это не столько хранилище, сколько "сессия" или "единица работы". Это удобный способ абстрагироваться от используемой вами технологии баз данных и просто пообщаться с чрезвычайно универсальным интерфейсом. Итак, давайте вместо этого переименуем его в ISession. Это шаблон, который я делал недавно.

public class PeopleRepository {
  private readonly ISession session;

  public PeopleRepository(ISession session) {
    this.session = session;
  }

  public virtual IEnumerable<Person> Active() {
    return session.Find<Person>(p => p.Active).OrderBy(p => p.LastName).ThenBy(p => p.FirstName);
  }

  public virtual IEnumerable<Person> ByLastName(string name) {
    return session.Find<Person>(p => p.Active && p.LastName.StartsWith(lastName)).OrderBy(p => p.LastName).ThenBy(p => p.FirstName);
  }

  public virtual void DeletePerson(int personId) { 
    // We don't really delete people; we mark them as inactive.
    var person = session.Single<Person>(p => p.Id == personId);
    person.Active = false;
    session.Update(person);
  }
}

В этой настройке ISession является общей ссылкой на хранилище данных. Однако PersonRepository очень специфичен для типов запросов и действий, выполняемых с объектом Person.

Надеюсь, это поможет.

0 голосов
/ 07 октября 2009

Вот пример:

http://dataguidance.codeplex.com/

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