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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With