开发者

Questions regarding Entity Framework + DDD

I'm having a difficult time finding straight forward examples of using EF in a DDD style pattern. This is also my first time employing DDD 开发者_运维问答and have a few questions regarding solution layout and how to employ some of the DDD patterns.

1) Most of the examples I've seen regarding using the Repository pattern w/ EF just show specialized Model interfaces such as IContactRepository and then a concrete type implementing the interface. Ideally, I'd love to use something like IRepository that has a basic set of functionality for CRUD ops. I could then create specialized repositories if if necessary such as IContactRepository : IRepository when necesary as most of my models won't need to be extended. Am I barking up the wrong tree? Can someone provide me w/ examples of this style of implementation?

2) Right now I have my solutio broken up into the following three projects: Models (contains my EDM), Repositories, and Services. Is this fitting or is there another layout approach I'm not considering and should be?

3) I've seen examples of repositories having a Query(Func<T>)/Query() methods that return IQueryable. Is this smelly or something frowned upon?


I'd like to answer #3...

I think it's less "smelly" and more "lazy". Here's a typical "repository" that I've been seeing around the internets...

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);
}

As far as I'm aware, this is less a repository and more a "session" or "unit of work". It's a handy way to abstract away whatever database technology you're using and just talk to an extremely generic interface instead. So let's rename it to an ISession, instead. This is the pattern I've been doing recently.

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);
  }
}

In this setup, the ISession is a generic link to the data store. The PersonRepository, however, is very specific to the types of queries and actions that are taken on a Person object.

Hope this helps.


We are currently using EF with DDD, but I would have to say that in its current implementation, EF isn't very suitable to this kind of architecture. The main problem is that the only way EF currently works is by having each 'Entity' derive from an EF-specific base class.

On the other hand, the whole point about Repositories is to abstract away the data access technology. The whole idea behind DDD is that the Domain Model should be unconstraind by implementation details such as the choice of data access technology. This means that domain objects should be defined so that they are Persistence-Ignorant.

In other words: You can't use the EF 'Entities' as domain objects, so in your DAL, you must manually write a lot of code that maps to and from the domain objects to the EF 'Entities'. That gets tired really fast.

I would definitely consider having IQueryable on a Repository to be a leaky abstraction, and it doesn't make a lot of sense in DDD parlance. If domain objects are cohesive units, it doesn't make a whole lot of sense selecting only certain 'columns' from them.

In EF for .NET 4.0 we will get Persistence Ignorance, so it should become better in the future...


Here is a sample:

http://dataguidance.codeplex.com/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜