How I Use The Generic Repository Pattern In Clean Architecture

preview_player
Показать описание

The generic repository pattern is precisely that - a repository pattern implementation that is generic. You won't benefit much from implementing it on top of EF Core.

Specific repositories are a different story, and they're common in DDD. I'll explain in the video how I use the specific repository pattern and use the generic repository pattern to reduce code duplication.

Join my weekly .NET newsletter:

Read my Blog here:

Subscribe for more:

Chapters
0:00 Specific repository in the Domain layer
1:26 Using the repositories in use cases
3:25 Why I like Specific repositories with Clean Architecture
5:13 Specific repository downsides
6:06 Creating a generic repository with EF Core
8:40 Refactoring to use the generic repository
11:04 Strongly typed IDs with generic repository
15:45 Solving breaking changes with Extract Interface refactoring
Рекомендации по теме
Комментарии
Автор

Adding a repository layer on top of EF is just wrapping one repository pattern with another. The DbSets in your context are already your repositories, and the DbContext itself implements the unit of work pattern.
It's worth bearing in mind that patterns are often derived from other languages (especially Java) that lack nice things like extension methods in C# so there's sometimes better ways to approach things. For example you can extend the DbSet<T> collections in your EF context with extension methods to add methods like GetProductById to DbSet<Product>. You can even add generic GetById methods to all your DbSets using a single extension method. It's much cleaner this way, with less code and less complexity.

dansmif
Автор

I like to use generic repositories these days, since many database providers - relational or not - support queryable linq and it's relatively easy to implement an in-memory cache or change tracking system for any of them that don't support EFCore. When I need a custom operation on the repository, lets say it due to a need of a very optimized query or bulk update or insert, then I create a specific method in the domain repository interface. This has worked very well for many projects I've worked on.

danilonotsys
Автор

This is an approach I used in a project where you had to connect to multiple providers via API and keep their information in our db, this helped a lot to reduce the code generated via the integration of every provider, and we could have a lot of providers almost seamlessly

victorgarcia
Автор

Nice video, i’d love to see a version of this with Dapper instead of efCore.

frankhalbach
Автор

When using generic repository pattern with EF I always liked to make the methods simple and return an Iqueryable so the inheriting class can modify the "Base query" and add to it. E. G the repository class has a getById but the inheriting class can call this, get the Iqueryable and add a where clause to it to filter further more but only actually executing once.

jonclark
Автор

Hey there. Long time sub from Cameroon. Keep up with videos, i learn a lot from them.

hkoueke
Автор

Valious tips Milan!! Depending of project, can be useful

alessandrohudson
Автор

Thanks for sharing your valuable knowledge.

i.paradox
Автор

Thank you for your answers. I will approach things like this in my future applications I don't know is it true or not. I will use repository pattern in basic crud operations becauase it is good especially when you want implement something like soft delete mechanism. But in complex queries no matter I use cqrs or not I will do in bussiness/application layer because it really gives complexity. I really see a lot solution people does not use select query and directly map into objects. What is the reason to get all the data from database and map to them. Because if you get 8 columns of data maybe you need 4 columns of it..Map after get all the data. Select after ToListAsync.All columns queired allready!. This is performance issue.If it is wrong to use dtos in repositories object or dynmaic i should do this operation in bussiness layer. So I should abstract away dbcontext because my application shouldn't reference persistence layer.I am really tired to search how to solve this. Thanks for the answer again.

sadkcoban
Автор

Patreon email coming in clutch to quickly absorb Milan's new content

xenofenus
Автор

Great video Milan. Would love to see how something like this would work with the MongoDB driver. First thought is that each collection is it's own property in the MongoDB context and can't just use the generic Set<> property. As far as I'm aware?

Flanno
Автор

Great video. if the app logic is complex. we better make a abstract class between actual service class and their interfaces. it is more flexible.

yiliang
Автор

The order and orderlines could be defined using the ownsmany-relationship, and efcore will handle the include for you, so you can skip the override.

svorskemattias
Автор

I'm learning a lot on your videos. 😁

I'm just wondering if, is it better to have a method GetAsync with a parameter of an expression (Expression<Func<TEntity, bool>> predicate = null) rather than adding a method GetByIdAsync ?

marcnacionales
Автор

It is interesting that you decided to define the repository interfaces within the domain project. I myself usually define them within the application layer, because it is actually the application that determines what exact data it needs, based on what the application actually does. The domain layer should not be bothered with that. Of course it does still own its own entities, value objects and contains all related domain logic.

One down side of my way however is that a lot of these repository interfaces end up in the Common area, since their usage often spans across multiple application microservices... And then also your reasoning does make sense and got me thinking about it once again.

I've yet to decide if we will be switching back to defining 'em in the domain layer after all :)

kp_xcess
Автор

Really good and concise video explaining the pattern. I have one question that I couldn't find an answer on. What if we are working with a DbContextFactory? How would the Repository and UnitOfWork class use the context in this case?

mocca
Автор

Awesome, love your explanation. Earned a subscriber. 💪

KristofGalNix
Автор

I really like this approach when using ef core with the repository pattern

feli
Автор

HI @MilanJovanovicTech, I really enjoy watching your tutorials. Please do you have any video on unit testing ef core async methods like AnyAsync, FirstOrDefaultAsync, e.t.c as well as AsNoTracking method?
Thanks

olamidejames
Автор

Thanks for this helpful video Milan! Wouldn't it be great to use this generic repository pattern with CQRS and only the Command uses it and the Query part still uses EF directly? Should be a good content for another video?

ARESCOM_PA