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.

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.

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.

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.

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.

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:

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.

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.

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.

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

@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.

@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.

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.

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:

@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.

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?

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.

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.

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.

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.

Ads

About Me

I'm the chief architect at 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.