DDD, Repositories and ORMs

One of the confusing aspects of those new to DDD is the concept of a Repository.  From Fowler’s Patterns of Enterprise Application Architecture, a Repository:

Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

Paraphrasing the various DDD sources, a Repository provides the ability to obtain a reference to an Aggregate root.  Not Entity, Value Object, but Aggregate root.  Each Save operation encapsulates the entire operation for saving a single Root and all of its child entities.  For example, given the model of a Root Person entity with child Address entities, a Save operation will save Person and Address, all in one operation, from the perspective of the client of the Repository.

From the client perspective, how an object is persisted is unimportant.  From the developer perspective, persistence is very important!  Many who follow DDD choose to use various ORMs to provide the persistence logic inside the Repository.

Because DDD does not prescribe a persistence technology, nor even a storage medium, using an ORM like NHibernate does not indicate you doing DDD.  Conversely, doing DDD does not predestine you into an ORM technology like NHibernate.  I could use the Cargo Cult metaphor, were it not for the Cargo Cult of folks using the Cargo Cult metaphor.

You can do DDD with stored procedures.  You can create Repositories for in-memory databases, all the LINQ implementations (including EF).  A Repository is a pattern, not a technology prescription.  It’s far more important to learn the concepts than jump to a technology, that’s the short bath to a bad experience.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in Domain-Driven Design. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://nichestone.com Nigel Sampson

    That was certainly an aha! moment for me when reading through some DDD style definitions, especially around specialised repositories. I remember thinking that’s going to lead to stupidly large amounts of them, but when you pare it back to the aggregates it makes a whole lot more sense.

    Nice post

  • http://www.tobinharris.com Tobin Harris

    Good point. I found myself recently revisiting Evans’s definition of a Repostitory.

    Lots of people are using Repository and DAO interchangeably. I see this especially where there are generic repositories such as:

    Repository.FindAll();

    I’m currently experimenting with the advice given by Evans, meaning:

    - One repository per aggregate root
    - Repository interfaces (e.g. IOrderRepository) reside in the domain model
    - Repository implementations (e.g. NHibernateOrderRepository) reside outside the domain (ala Onion Architecture)
    - Queries *inside* the repository, accessed by plain method calls (repos.FindOverdueOrders()). Or they take specifications.

    Not sure I’m happy with it yet. Using “Repository as DAO” and having queries built *outside* the repository feels simpler IMHO.

  • http://colinjack.blogspot.com Colin Jack

    Couldn’t agree more, my personal view is the vast majority of repositories in recent blog posts have nothing to do with Evans’ pattern, unfortunately Fowler was less specific in his description of the pattern so maybe they are following his pattern?

    @Tobin
    I think “Repository.FindAll” style can work especially in a non-DDD (maybe ActiveRecord) situation. However I’m definitely prefer the approach Evans puts forward if you are using DDD.

  • http://www.tobinharris.com Tobin Harris

    Me too. And you if you do want to benefit from the ease of Repository, whilst using the DDD approach, you can always use generic repositories as DAO objects, and delegate to them from within your DDD repositories.

    public class OrderRepository : IOrderRepository
    {
    //using Rhino repositories behind the scenes
    readonly IRepository _orders = IoC.Resove>();
    readonly IRepository _lineItems = IoC.Resove>();

    //….
    }

    Don’t know if this is a good idea, but I’m playing with it right now!

  • http://jimmybogard.lostechies.com Jimmy Bogard

    @Tobin

    I think in the way you just showed, you may want to call the generic ones you’re doing “IDataMapper” – as it looks like the PoEAA Data Mapper pattern. That might clear up confusion between the roles of the different repositories you have going on:

    http://martinfowler.com/eaaCatalog/dataMapper.html

    +1 for PoEAA – great book that just keeps getting better with age.

  • http://www.JeremyJarrell.com Jeremy Jarrell

    Totally agree. One of the gotchas with a lot of these types of tools is that their most obvious benefits often aren’t their most important. I.e., TDD isn’t about unit testing, it’s about malleability of code, IoCs aren’t about swapping out fake implementations for real ones, they’re about easing the construction (and changing) of objects with a lot of injected dependencies. By the same token OR/Ms aren’t about automatic database access, they’re about completely decoupling us from our persistence layers.

    Lean the fundamentals first and you’ll appreciate the tools much more for it.

  • Jeremy Gray

    It is certainly clear that there should not be repositories for the entities within any given aggregate root, but in my travels I have yet to see anything that suggests that only Aggregate Roots can have repositories. Not every entity need be forced into an aggregate root, and as such entities not contained within aggregate roots can most certainly have repositories.

  • http://colinjack.blogspot.com Colin Jack

    @Jeremy Gray
    Not sure I follow what you are saying.

    DDD the book suggests that only aggregate roots should have repositories and that entities/value objects live within aggregates.

  • http://schambers.lostechies.com Sean Chambers

    Another point here is that Evans states that Repositories are used to manage middle and end of an entities lifecycle, while factories manage the creation of their lifecycle. Not in all instances, but most that require complex setup of Entities.

  • http://www.tobinharris.com Tobin Harris

    @bogardj

    PoEAA is ace, agreed. In fact, Mr Fowler kindly even mentioned me in the credits :) IDataMapper could indeed be a more accurate description of the IRepository class I’m using. Will add this into my musing :)

    I think my confusion comes from the the various sightings of Repositories in the wild, and a slight lack of experience with all the patterns.

    In the example above, I’m using Ayendes (brilliant) NHibernate repository class found in Rhino Commons.

    http://www.ayende.com/Blog/archive/2007/06/08/Rhino-Commons-RepositoryltTgt-and-Unit-Of-Work.aspx

    I’ve also seen Repository classes used in Fluent NHibernate.

    These repositories are a bit like DAOs, and possibly DataMappers. They’re non-specialized and generic, and give a good bang for the buck when it comes to data access (as does the Active Record pattern).

    When using these repositories, it seems easier to put the responsibility of query construction into the controllers (or services or business layer, depending on your terminology). This worries me a bit, because persistence knowledge is bleeding out of the repository into surrounding code. I have lived with this in the past, but would like to find a better way.

    Anyway, it seems that the repository implementation you pick has side effects on where responsibilities reside in your archtecture; If you have a specialised repository (ala DDD) then I’d guess that most query construction happens in the repository itself, and clients get results by simply calling public methods with parameters. This makes sense to me, it feels neat and clean. If you have non-specialised repositories, query construction happens in the services/controllers, and persistence concerns affect more layers.

    Perhaps my understanding of this stuff isn’t totally spot on, but that’s how I see it now. Carification would be GREAT :)

    Essentially, I just want to learn to build clean, simple, maintainable, understandable, testable software in the least amount of code ;-)

    @Jeremy Jarrell
    It’s a steep learning curve, but I’ll keep at it!

  • http://jimmybogard.lostechies.com Jimmy Bogard

    @Tobin

    My personal repositories have specialized query methods, such as “FindValidCustomers”, where I specialize the query inside it.

    Others prefer a Domain service on top, that does the custom Where clauses, so to speak. Both are valid, and just a personal preference.

  • http://www.tobinharris.com Tobin Harris

    @bogardj

    Thanks. Do you also have a domain service which handles transaction management? Also, are your entities aware of repositories? For example:

    public class User
    {
    IOrderRepository _repos;

    public void SetUsername(name)
    {
    if( _repos.UsernameInUse(name) )
    //…
    }
    }

  • http://colinjack.blogspot.com Colin Jack

    @Tobin
    “These repositories are a bit like DAOs, and possibly DataMappers. They’re non-specialized and generic, and give a good bang for the buck when it comes to data access (as does the Active Record pattern).”

    Definitely agree.

    “Perhaps my understanding of this stuff isn’t totally spot on, but that’s how I see it now. Carification would be GREAT :)

    Thats exactly how I see it too. Passing specifications into the repositories is also a useful option, its intention revealing and stops the queries leaking out and can prove more extensible than the explicit FindValidCustomers option. I use both approaches.

    “Thanks. Do you also have a domain service which handles transaction management? Also, are your entities aware of repositories? For example:”

    I know this was aimed at Jimmy but couldn’t resist putting in my 2c too :)

    In my view domain services don’t get involved in transactions, they only ever handle domain logic and (in many cases) communication with repositories for simple CRUD. In my previous projects transactions happen in application services which are a layer above.

    Entities contacting repositories is a topic of contention, lots of disagreement on this in the DDD forum. Personally my entities never contact repositories. In fact I’ve gone one step further in the past and tried to ensure my domain services didn’t contact repositories either, moving all that out to keep the domain services really clean and focussed. Still not sure whether that second choice was a help or a hinderance though.

  • http://www.tobinharris.com Tobin Harris

    @Colin Jack

    Thanks for the info, very interesting.

    So, if I understand your approach, you’re using the following (I’ve added some assumptions, don’t want to put words in your mouth!):

    * Specialised Repositories (rather than generic multi-purposes DAO like ones)
    * Repositories allow clients to query by accepting specification objects, or simple method calls.
    * You have domain services for domain specific responsibilities and business logic that don’t fit well in Entities or Repositories (ala DDD definition of Services).
    * Entities that don’t depend on Repositories. Full stop.
    * You have application services that communicate with domain model (entities, repositories, domain services) to fulfill use cases.
    * Application services also handle transactions.

    Sound about right? Do you use DAO under the hood in your repositories? Are you using a OR/M?

  • http://colinjack.blogspot.com Colin Jack

    @Tobin
    Yeah thats it exactly, in fact I might just copy & paste that into a new blog entry at some stage :)

    Only things I’d want to add is that in my case application services would also handle things like sending e-mails/messages and other application specific logic. If you have multiple GUI’s that are part of the same system (e.g. admin GUI and web GUI) then you may want to share the logic in these application service, but thats easily done and doesn’t really change the overall approach.

    My repositories don’t use DAO’s under the hood, considered that approach and Jimmy’s NWorkspace style idea but I decided against it so testing repositories is something I do against the DB. However once Linq To NHibernate is a little further along I’ll reconsider this (e.g. by having an IUnitOfWork implemented by the NHibernate session and by an in-memory unit of work that works against collections).

    I’m not saying its the only way to work though, but its worked for me.

    What do you think anyway, does it match what you’ve been doing?

  • http://jimmybogard.lostechies.com Jimmy Bogard

    @Tobin

    Regarding transactions, on many occasions I’ll leave that up to the underlying infrastructure to handle that, such as ASP.NET or WCF. Transactions committed at the end of the request, transparent to the services, with an ambient unit of work going on.

  • http://www.tobinharris.com Tobin Harris

    @Colin

    Cool, all makes sense. I test against the DB too, using in-memory DBs more and more (it’s a good compramise IMHO). So how do your repositories talk to the DB?

    In the past, the patterns I’ve used are similar to this (NOTE: I really want to improve on it, hence this dicsussion :) )

    * Domain model: Entities + Repositories (and sometimes Query objects)
    * Repositories: the non-specialised DAO-style repositories
    * Entities and Repositories are tested against the DB.
    * Controller classes (i.e the C in MVC)
    * Queries: usually constructed in controller classes, using persistence aware language (HQL for example). Query objects also used for more complex cases.
    * Transaction management also takes place in controller classes
    * Calling other services (email etc) also takes place in controller classes
    * Controllers don’t get tested cause they’re too fat

    On small quick apps it’s ok(ish). But it doesn’t scale well as apps grow. The problems are obviously that you end up with a hugely obese controller that isn’t testable and ends up with too many responsibilities (and a good helping of spaghetti code to boot).

    I’m now playing with something similar to what you have, hence my questions :) Ideally I’d have:

    * Domain model of Entities + Repositories + Domain Services (if needed)
    * Specialised repositories to encapsulate data access and contain queries (or accept query specifications).
    * Repositories would use some DataMapper or DAO internally to make data access easier (rather than raw NHibernate/Linq 2 SQL/XML/Whatever access).
    * Application Services (or Controllers, as Ayende would call them) to talk to Domain Model, coorinate transactions, and do other app specific logic as you mentioned.

    Do you clients (i.e. an aspx codebehind) talk to App Services only as a rule?

  • http://colinjack.blogspot.com Colin Jack

    @bogardj
    Quite right, in the web context I just use session-per-request.

  • http://colinjack.blogspot.com Colin Jack

    @Tobin
    In-memory interests me but the issue is getting static/reference data in (e.g. lists of Countries) into the database? Thats always been the sticky point for me.

    So far the repositories have just used HQL/Linq or, where necessary, SQL.

    Does sound like you’re going for something very similiar, be very interested to hear you get on.

    I’d also be interested to hear what others are doing regarding clients always talkin to app services. I’ve tended let the apps talk to the domain directly where applicable but I’d be interested in hearing how you and Jimmy approach this.

  • http://www.tobinharris.com Tobin Harris

    @bogardj

    Thanks for the pointers regarding transactions and repositories. I always liked the idea of transaction demarkation using attributes , which is now possible with Castle. E.g

    [Transaction(Mode.Requires)]

    @Colin

    I’ve always used Object Mother for setting up reference data in tests. The only thing is, if you have a lot of it, then you’ll experience speed problems.

    In the case of a huge list of countries, you could always have an Object Mother method that only sets up 1 or 2 countries, which might be enough to satisfy the test case. Also, don’t set it up in test fixtures that don’t need it.

  • Milo Hyson

    @Colin Jack

    I’m a bit confused as to from where exactly the idea comes that “only aggregate roots should have repositories.” I have Evans’ book open in front of me as I type this, and I’ll be damned if I can see anywhere he states this. It also makes no logical sense.

    The purpose of a repository, as per Evans, is to provide a means of obtaining references to existing domain objects via global accessibility (as opposed to traversal from another object). Suppose that a given design contains no aggregates, but only simple entities without any embedded value objects. By your statement, no repositories should exist. How then is one to obtain references to the existing entities?

  • http://jimmybogard.lostechies.com Jimmy Bogard

    @Milo

    A standalone Entity is its own Aggregate, and Root. The idea is that you have Entities, but Aggregates are how you draw boundaries around them. Every Entity must belong to an Aggregate, and every Aggregate has a root. That’s how you arrive at the one Repository per Aggregate idea.

  • Milo Hyson

    @bogardj

    With all due respect, I don’t think you’re quite grasping the concept of an aggregate. According to both a standard English dictionary and Evans’ book, an aggregate is a combination of separate elements into a single unit. By that definition, a standalone element cannot be an aggregate.

    As for the delineation of boundaries, standalone objects already do this. The creation of an additional border is only necessary when more than one object is involved. This allows enforcement of the group’s internal cohesion. Standalone objects enforce their own cohesion.

  • http://jimmybogard.lostechies.com Jimmy Bogard

    @Milo

    Fair enough. I think that’s just semantics of the meaning of the word, not a representation of the concept. It’s clear that not every entity deserves its own Repository, namely child entities in an Aggregate. That was the whole point of Colin’s comment.

  • mogadanez

    how about physical separtaion?

    for example if Enity & Domain Services are not use Repositories – I want do it physically( put in separate assembly), not logically.

    So, let’s me place repositories and Hibernate mapping in separate assembly( e.q. MyApp.Data, as in [SharpArchitectecture(http://code.google.com/p/sharp-architecture/) )

    Where must I place repository interfaces? 1. MyApp.Data 2. MyApp.Model 3. Another, separate aseembly?

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @mogadanez

    Repositories are part of the domain, so I put the interfaces in MyApp.Domain. Services are part of the domain, so I put at least domain services in MyApp.Domain.

  • elguaro

    I think I’m missing something very fundamental about DDD’s repositories. How do you Update something inside it? A Repository is meant to behave like a collection which dont normally have an update method.

    The common approach seems to be you find the object you want first and set the new values on it.

    Customer customer = customerRepository.find(id);
    customer.Name = newName;

    The new name is later persisted by the Unit of Work.

    This bothers me because I have to do a get before I can update something. I should be able to just add an Update to the UofW (i.e NHibernate’s Session.Update); but where can I do that if not in a Repository?

    How do you handle updates?

  • Milo Hyson

    @elguaro

    You’re assuming that all collections use a store-by-reference model in which only references to the objects are stored. There’s nothing that says you cannot use a store-by-value model in which a copy of the object data is recorded. In such a case, simply use get() and set() methods with the latter adding or overwriting an object as appropriate.