Generic Repository Pattern With EF Core - Why It Sucks

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
generic repository pattern it's one of the most infamous design patterns out there in this video we're going to implement it and then I'm going to explain why I think this is actually an anti-batter let's start off by defining the contract for the interface of our generic repository I'm going to add the interface in our application layer and I'm just going to call it I repository of course we're going to make it a generic interface so let's give it a generic argument of T entity which is going to represent our entity type this interface should have all of the methods that you could possibly want inside of a generic repository so let's add a few methods and then see how we can implement this so I want to add a method which is going to return a task and a list of T entities and we're going to call it get all async so this one is going to just return all of the entities for this repository then we want to have another method which is going to return a null ability entity and we're going to call it get by ID now the tricky part here is which type is the ID you can also add the generic argument here for the T entity ID but let's just assume for simplicity's sake that this is actually going to be a good so I'm just going to add one argument and I'm going to add the async suffix so we have our get all and get by ID methods let's also add methods for inserting updating and deleting entities so we're going to say void insert and we're going to pass it at the entity argument and then the same for the update and for the delete for delete you need to specify an T entity and you're done so these are the generic repository methods and we're also going to add one more method for saving the changes in the database so let's call it save changes async and let's not give it any arguments just to make it simple so these methods will cover most of the use cases that you have but what happens when you need to write a very custom query and you don't have a method satisfying that query what you typically do in that case is have a method in the generic repository returning an like variable and you call it get variable and then you use this method to get back a queryable instance and just Implement whatever query you need let's see how we're going to implement the generic repository let's say in the persistence project I'm going to add a repository class and we're going to use it to implement our generic repository so let's make this class public we're going to make it generic of the entity and is going to implement the I repository interface of the entity let's add the missing members how are we going to implement this so we're going to use EF core and let's inject our application DB context so we're going to call it context and inject it from The Constructor and now we're going to use our EF core DB context to implement the generic repository methods so for the get all async let's make it asynchronous and what you do is you say context and then you grab the DB set of your T entity and you can see that there's a constraint here that it has to be a reference type so what we have to do is we have to say that the entity is a class and now you won't be getting a compile error so now you just need to add two list async and you need to of course await this call because this is asynchronous and this is the implementation of the get all async method for the getby ID async method we're going to start by making it asynchronous and we're going to say return await context we're going to grab the set of the entity and we can call Define async method and pass in our primary key for the get variable this is super simple you just return the actual DB set and that is actually the variable so you're just going to say return the actual set for the insert update and delete methods we would have context set and grab the entity and we just call the respective add update or remove methods so here we would have update here we would have remove and then in the end we just call the context save changes method so save changes async we can for example return the task returned by the save changes method or we could even await it if we wanted to it doesn't matter because in the end the one calling this repository will have to await the save changes method to persist the changes in the database you can see this is relatively straightforward because it's just a wrapper around the F core so how do we actually configure this with dependency injection and how do we use it in our dependency injection class in the persistence project we're going to add a scope service for our repositories by calling adscoped and we need to specify our generic repository type so this is going to be the I repository interface and we're going to specify the repository implementation as this service that is provided when the interface is requested so we're going to say type of Repository and this will take care of configuring our generic repository with dependency injection so let's finally see how we can use the generic repository in our application so here I'm going to replace the use of our application DB context with the generic repository so I'm just going to inject the repository at the bottom so here we need the customers repository and we also need the orders repository so how you do that is you inject an i repository of customer and you call it customers repository and you're also going to need an i repository of order and you can call it orders Repository and now let's inject these from our Constructor so let me just align this vertically so you can see what's going on so we're injecting our repositories from The Constructor and let's see how we're going to use them so we need to replace the usage of our DB context so this is going to be customers repository get by ID async so we're going to just pass in the request customer ID assuming that the guide is the primary key which it is in the database level The Next Step would be replacing this call here for inserting the order so this is going to be order repository insert and we're going to pass it the order entity the last part here was just saving the changes in the database and we were previously using the DB context but now we need to use one of the repositories now it really is strange that you can either call customers or orders repository let's say we call the orders repository and they are both going to work just fine since they are wrapping the same DB context so so instead of working with the DB context we are now working with two repository interfaces the customers and the orders Repository it's a little confusing which repository should call the save changes method and let's not even begin with actually fetching some random query for example let's go to the get order query Handler and let's say you have to implement this here so we don't have a method in our repository to implement a query like this so this would turn into let me inject the orders repository to show you so let's say I repository of order this is going to be called the orders repository and let's inject it from The Constructor so now instead of context here we're going to say orders repository and get variable so we replaced the nice usage of the DB context with exposing the variable to be able to query the orders entity in my opinion the generic repository pattern is just a useless wrapper around EF core's DB context you'll have to expose the I queryable instance to be able to write custom queries and at that point why not just use EF core directly although I think the generic repository pattern is pointless I think there's value in the specific repository pattern which is common in domain driven design where your repositories only return your Aggregates or entities and you have very specific methods on your interface returning only what you need in your domain but you wouldn't have the save changes method exposed you would rather create an i unit of work abstraction and expose the same changes method on that make sure to smash that like button subscribe to my channel and take a look at the video that you can see right now stay awesome
Info
Channel: Milan Jovanović
Views: 30,744
Rating: undefined out of 5
Keywords: generic repository pattern, generic repository pattern in asp.net core mvc, generic repository pattern c#, generic repository pattern in asp.net core, generic repository pattern entity framework core, generic repository pattern c# dapper, generic repository pattern in asp.net core web api, repository pattern ef core, generic repository pattern ef core, generic repository c#, repository pattern c#, anti-pattern, ef core, entity framework core
Id: Bz5JCbWnaHo
Channel Id: undefined
Length: 9min 33sec (573 seconds)
Published: Fri Apr 07 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.