Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
DDD: The Repository Pattern

I seem to have taken a fairly long time to get here, and it has been mentioned in passing, but now we get to the last major part of the Domain Driven Design picture – Repository.

In traditional architectures, your application talks to some kind of database layer, and asks it to save or retrieve your objects. DDD is slightly different, after all, remember I said “There is no database

Of course, there is a high likelihood you do *actually* have a database, but the Repository pattern ensures you need to take little to no concern of it within your domain.

Download the eBook of the series so far …

Repository Is Just A Collection

The primary thing that differentiates a Repository from a traditional data access layer is that it is to all intents and purposes a Collection semantic – just like IList<T> in .Net

Repository Is Just A Facade

While Repository pretends to be a Collection to your domain, it is actually just a variation on the Facade pattern – it takes a complex subsystem (persistence or the database), and wraps it with a simpler interface (a Collection)

Repository Is Not A Data Access Layer

Well, at least not in the traditional sense – it doesn’t talk in terms of “data” it talks in terms of Aggregate Roots. You can tell your Repository to add an Aggregate Root into it’s collection, or you can ask it for a particular Aggregate Root. When you remember that Aggregate Roots may comprise one or many Entities and Value Objects, this makes it fairly different to a traditional DAL that returns you back a set of rows from your database tables.

Repository Is Persistence Ignorance

An important part of any properly decoupled architecture is Persistence Ignorance – your application or domain should be completely unaware of how or even if your data is persisted – it should just expect it to happen. In DDD the Repository pattern achieves this by a combination of the first three headings above – it pretends to be a collection, acts as a facade onto your actual persistence layer, and it does not act like a DAL

The Repository is the seam between your domain, and the technical implementation you use to store and retrieve your data.

Repository Is A Collection … Of Aggregate Roots

The Repository pattern is not just a thin DAL – it is responsible for talking in Aggregate Roots only. A single Aggregate may contain 2,3 or more Entities and Value objects – so our Order entity may also contain OrderLines, there would not be a Repository for OrderLines, it would be up to the Order Repository to persist an Order and all the OrderLines it contains.

What Sits Behind A Repository

Pretty much anything you like.

Yep, you heard it right. You could have a database, or you could have many different databases. You could use relational databases, or object databases. You could have an in memory database, or a singleton containing a list of in memory items. You could have a REST layer, or a set of SOA services, or a file system, or an in memory cache…

You can have pretty much anything – your only limitation is that the Repository should be able to act like a Collection to your domain.

This flexibility is a key difference between Repository and traditional data access techniques.

In Conclusion

The Repository pattern is a Facade, that abstracts your persistence away from your Domain. On one side it pretends to be a collection – on the other it deals with the technical concerns of your persistence implementation.

Repository provides us with a mechanism to achieve Persistence Ignorance in our Domain.

Reference:

InfoQ Free eBook : Domain Driven Design Quickly
Domain-Driven Design: Tackling Complexity in the Heart of Software (Eric Evans)

Repositories

Previously:

1) Domain Driven Design: A Step by Step Guide
2) DDD: The Ubiquitous Language
3) DDD: Bounded Contexts
4) DDD: There Is No Database
5) DDD: Command Query Separation as an Architectural Concept
6) DDD: Entities and Value Objects
7) DDD: Where is the Code?
8) DDD: Download an eBook of the Series
9) DDD: Aggregates and Aggregate Roots
10) DDD: Services
11) DDD: What Kind Of Applications Is It Suited To?

del.icio.us Tags: DDD,Domain Driven Design,Practices and Principles


Posted 02-20-2009 8:30 AM by Jak Charlton

[Advertisement]

Comments

Harry M wrote re: DDD: The Repository Pattern
on 02-20-2009 5:02 AM

The big question I have about repositories, is "how dumb should they be". At my company, our repo provide a PI way of accessing the database and it works for that.

My question is, does it make sense to have repositories which automatically apply filters and stuff to queries. e.g. the repository in the main app automatically filters any record with disabled = 1. Maybe in a multi tenancy app, you could use a repo that automatuically hides records where companyId != currentUser.CompanyId.

Someone gave an example the other day about entities becoming invalid in their state only in certain circumstances - the example was about an incomplete form - still a form, but you don't want to put it in the filing cabinet (or FormRepo) until its done. Should the FormRepo be the thing which validates the form is complete?

Jak Charlton wrote re: DDD: The Repository Pattern
on 02-20-2009 5:20 AM

@Harry

A couple of separate points there ....

Yes, the Repository can do things like applying a Deleted filter to all queries it carries out ... the Domain is not and should never be aware of something like that, so that is the job of the Repository

Under normal circumstances- don't let entities enter an invalid state.

If you are doing something like partially filling a form, then this should be done UI side until the form is completed, and the a DTO or message/command should be sent to the domain to turn this into an Entity and persist.

If your Form can be saved part way through - then half a form is still a valid state according to your domain logic.

The last line of validation is the Repository, but the logic for that validation shouldn't be in the Repository, it should be on the domain Entity, a Service, a Specification or similar ...

Validation was recently covered by Derick and Billy - I will touch on it later in this series:

www.lostechies.com/.../ddd-question-where-does-input-validation-belong.aspx

devlicio.us/.../a-response-to-validation-in-a-ddd-world.aspx

Hope that helps

DotNetShoutout wrote DDD: The Repository Pattern - Casey Charlton - Insane World
on 02-20-2009 9:52 AM

Thank you for submitting this cool story - Trackback from DotNetShoutout

Alex Simkin wrote re: DDD: The Repository Pattern
on 02-20-2009 12:42 PM

I asked this question on StackOverflow but didn't get a good responce.

Let assume that we need to perform some 'bulk' operation with entities, and the number of entities makes it absolutely impossible to retrieve them into memory. I.e. operation can only be performed in the database.

Where is the place for such 'bulk' operation? Should it be a method on repository?

Casey wrote re: DDD: The Repository Pattern
on 02-20-2009 12:54 PM

bulk operations don't work so well... I presume you mean the equivalent of "Update Customer Set Prefered=true Where DOB<1/1/1960"

In that case, a method on the Repository like .UpdateAllWhereDobBefore(date) ... That method may call an ORM, or may call a stored proc

Your other alternative is to put bulk operations in their own bounded context

A rather contrived example I agree, does it cover what you meant?

Alex Simkin wrote re: DDD: The Repository Pattern
on 02-20-2009 1:10 PM

That's exactly what I have ment, but isn't it a violation of a whole number of principles starting with DRY. You will have duplication in

Customer.MakePreferred()

and

CustomerRepository.MakePreferredIfMatchesCriteria(...)

Joe wrote re: DDD: The Repository Pattern
on 02-20-2009 1:23 PM

Can you comment on how you'd implement lazy-loading with a repository?  Is it ok for entities to call into the repository to lazy load properties, or would you implement virtual proxy objects to use in properties, which in turn would call into the repositories?

Jak Charlton wrote re: DDD: The Repository Pattern
on 02-20-2009 1:46 PM

@Alex

Well you aren't violating DRY if the two methods on the Repository both exist in your domain, and therefore fundamentally in your UL. The second is used with Specification (to be covered soon) ... so you would do something like .MakePreferred(ISpecification specification), the first would just be an overload in your example - behind the scenes in their implementation they may use exactly the same mechanism (both use HQL in NH, or both use a the same stored proc)

DRY would only apply if you coded the same code in two places, the Repository allows you to use the same code, but for two similar operations

Jak Charlton wrote re: DDD: The Repository Pattern
on 02-20-2009 1:51 PM

@Joe

First option if you need lazy loading, is use something that supports it and handles it for you - lazy loading is a horrible thing to code.

If you use NHibernate for example, lazy loading is "free", as it creates all the proxies automatically. The proxies would not call the Repsoitory, then would use the NH session to retrieve the entities directly.

Manually coding a lazy loading mechanism is a much larger subject, but the entities wouldn't call to the Repository, they would call your data access layer directly - the Repository is a Facade for the benefit of your domain and application, not for a framework concern like lazy loading.

Also .. bear in mind... lazy loading is something to use with caution - in some scenarios it can be useful, but often it is used out of laziness...

Sometimes you should just get the data you realistically need - so for example, you may have a Document Repository that retrieves Documents, and a DocumentSummary Repository which retrieves Documents without the binary file attachment ... two Entities that are similar, have their own Repository, but talk to the same data source.

Casey Charlton - Insane World wrote DDD: Living In The Enterprise
on 02-21-2009 4:25 AM

No, not that Enterprise! The other Enterprise – the big amorphous one that organisation spent a fortune

Community Blogs wrote DDD: Living In The Enterprise
on 02-21-2009 4:48 AM

No, not that Enterprise! The other Enterprise – the big amorphous one that organisation spent a fortune

Insane World wrote DDD: Living In The Enterprise
on 02-21-2009 10:42 AM

No, not that Enterprise! The other Enterprise – the big amorphous one that organisation spent a fortune

DDD Step By Step wrote DDD: Living In The Enterprise
on 02-22-2009 3:37 PM

No, not that Enterprise! The other Enterprise – the big amorphous one that organisation spent a fortune

Reflective Perspective - Chris Alcock » The Morning Brew #292 wrote Reflective Perspective - Chris Alcock &raquo; The Morning Brew #292
on 02-23-2009 3:38 AM

Pingback from  Reflective Perspective - Chris Alcock  &raquo; The Morning Brew #292

Insane World wrote DDD: Living In The Enterprise
on 02-26-2009 4:08 PM

No, not that Enterprise! The other Enterprise – the big amorphous one that organisation spent a fortune

IHateSpaghetti {code} wrote Blog Carnival #14
on 03-01-2009 1:08 PM

Software architecture Evolutionary Design and Acyclic componentization by Patrick Smacchia Carnival of

Разработка приложений wrote Немного о проектировании: паттерны из мира ORM
on 01-18-2010 5:34 AM

Наверняка, каждый программист слышал о паттернах (шаблонах) проектирования, читал классику , и с той

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)