Database – To Repository Or Not To Repository

databasedependency-injectiondesign-patternsdomain-driven-designrepository

When I first learnt about Domain Driven Design, I was also introduced to the repository and unit of work patterns that once seemed to be top notch for the cool kids that threw SQL queries like cavemans against databases. The deeper I got into that topic, the more I learnt that they don't seem to be necessary anymore because of ORMs like EF and NHibernate that implement both unit of work and repositories into one API, called session or context.

Now I'm unsure what to do. To repository or not to repository. I really understand the argument that such leaky abstractions only over-complicate things while adding absolutely nothing that may simplify data access, however, it doesn't feel right to couple every possible aspect of my application to e.g. Entity Framework. Usually, I follow a few simple guidelines:

  1. The domain layer is the heart of the system, containing entities, services, repositories…
  2. The infrastructure layer provides implementations of domain interfaces of a infrastructural concern, e.g. file, database, protocols..
  3. The application layer hosts a composition root that wire things up and orchestrates everything.

My solutions usually look like this:

Domain.Module1
Domain.Module2
    IModule2Repo
    IModule2Service
    Module2
Infrastructure.Persistence
    Repositories
        EntityFrameworkRepositoryBase
MyApp
    Boostrapper
        -> inject EntityFrameworkRepositoryBase into IRepository etc.

I keep my domain layer clean by using a IRepository<'T> which is also a domain concern not depending on anything else that tells me how to access data. When I now would make a concrete implementation of IModule2Service that requires data access, I would have to inject DbContext and by this, coupling it directly to the infrastructure layer.
(Coming to Visual Studio project, this can end up really tricky because of circular dependencies!)

Additionally What can be an alternative to depositories and fucktons of works? CQRS? How does one abstract a pure infrastructural framework?

Best Answer

Engineering is all about compromises. And so is software development. Right now, I believe only other option, that would be simpler, is to work directly with ORM. But like you said, that might lock you into specific persistence framework.

So you have to ask yourself "Is the additional complexity worth the decoupling of your code from persistence". Every time I hear people say they want to decouple their code from persistence I ask "How many times in your career did you change your persistence framework?"

The problems I see with repositories is that they make common changes harder. Eg. adding new way to query an aggregate. And they make uncommon changes (supposedly) easier. Eg. changing implementation of repositories.

Then there is also the unit-testing argument, to which I say "If persistence framework doesn't allow you to mock a database, either in memory or locally, then it is not worth using the framework at all."