Generic Repository and Unit of Work .NET 7: A Comprehensive Guide

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
It is very essential to have a data access strategy that will stand the test of time in this video. Will we implement the generic repository pattern but enables developer to have a single repository for all CRUD operations for each and every entity? This channel offers rewards. We have a free mailing list that once you sign up, you have access to Microsoft eBooks. Cheat Sheet And a weekly tutorial that I will create for those who like to take it a step further and ensure that we continue making free content. Please support this channel and Patreon you have instant access to this video source code exclusive content that's not here on YouTube. You'll be added to our Private Discord server and more The mailing list and the patreon links are found in the description below What are the prerequisites? Although I will do my best to explain all the concepts in a beginner friendly way. If you have the following knowledge and tools, it will be easier for you to follow. Visual Studio 2022 dot net SDK seven installed a basic knowledge of C Sharp and a basic understanding of entity framework core. But like I said, I would do my best to explain. You're going to create a movie management API. You're going to use this to demonstrate how one can implement a generic repository pattern in their project. So here I've got my Visual Studio open and we're going to create a new project. So head over to create a new project and we're going to select a blank application. So I want to start everything from scratch. So open a blank solution and we're going to call this CU for code unparalleled to CU. Movie Management Service We want to hit create our blank solution is created. We're going to create three projects. The first one is going to be the API, which is going to provide the endpoints to our client. The second project will be our domain. Our domain is going to store the model class and our interfaces. The domain will be responsible for the business logic of our application. Then the third project is going to be data access. This will make the actual read write requests to the database operation. I want you to right click on the solution select add the new project then select ASP Dot net core Web API. If it's not all your recent templates, then you might go here and type that on it. Dot net core Web API. Don't confuse with web app its web API, so select that. Then you're going to click next We are going to call this movie management dot API and then we're going to go next. So we are using the dot net seven framework It's the latest came out just the week. You're going to configure for https You're going to use controllers and then open API support, which will enable you to see the to test your API using Swagger. Then they want to click create. So by default, Microsoft comes with controller that's called weather forecast. We're going to delete that and also come to the weather forecast class. We're going to delete that. So our API is done. So this will be responsible for whoever wants to continue our API. Then we're going to have the domain, the domain is going to have the logic of the business. So I want you to right click on a solution, then select new project. This time it's going to be a class library. So select class library hit next college movie movie management dot domain and you're going to hit next select the dot net 7 SDK and then you're going to click Create and go ahead and delete the class, which comes automatically with that. And then we're going to repeat the same process and create the movie management project. And this class library is going to be data access so call that movie management dot data access select the dot net seven framework click create. And I want you to go ahead and also delete the class library. So we have three projects which we're going to use we've got the API, Data access and the domain. Now in a, in a movie management system, you're going to have entities and these are the ones that we're going to focus on, on how to talk to. So in this scenario, we're going to have four just for the sake of demonstration. So if you're watching this video, you're so lucky because you're going to learn entity framework core relationships, which I feel like it's very, very crucial. So we're going to focus on one to many many, to many and one to one so that not only are you going to understand the pattern itself, but also learn a few things about entity framework. So that will be a bonus for you. So we're going to have, four entities now us per our conversion here. The domain is what has the business logic. So the entries will be the domain. This is where the business logic is going to be. So I want you to create a folder folder called entities in the domain project. So create a folder called entities and then we're going to have four entities. Let me just make that capital letter OK? Within that, you're going to create an entity which it's a class, obviously it's going to be called actor. The first one, make that public now an actor can have an ID an actor can have a first name all right. So first name just default. That to string dot empty actor could have well, last name last name all right. String dot empty. There you go. An actor can can be in many movies so one actor can act in into many more. So we want to also introduce a one to many relationship here which also uses learn so we're going to create a list of movie now movies is not yet created but don't don't worry we are going to create that so an actor can star in many movies and this movie is not yet created so one actor can be in many movies So you will see that in entity framework We're going to represent that with a list. There is no need to add any configurations but you could add if you want. But we believe in configuration. We would believe in convection over configuration. So entity framework once it sees this, it should be able to know what type of relationship that is. Again, we also expect an actor to have at least no to have one biography biography. Biography. All right, so get and set. So an actor should have a biography. An actor should have at least one biography. So if it's one, we're going to represent it as that object through, which is going to be in biography. Now, you see, it's saying these two errors. It means we have to go ahead and create those two classes. So entities you going to add an entity called movie, make it public and also create another entity called biography class. Call a class biography, make it public all right. So let's make this a nullable so that when you're creating a movie, it shouldn't be a must when you're creating an actor, shouldn't be a must to add the others. So a movie what sort of what does a movie have? A movie should have an ID, obviously a movie should have I would say a name. So a movie should have a name. And we're going to default that to string dot empty and going can have a description if you want again, let's default that to string or empty string dot empty rather sorry. And a movie can have an actor is linked to a movie. So one actor can be in many movies, but many movies can have one actor. That's just our business case. So you're going to bring in here public actor and actor like. So now to cement that sort of relationship, I am going to make it nullable To cement that sort of relationship, you're going to need to have what would link an actor to a movie. It's going to be the actor ID. So the primary key in actor is actor id the foreign key in the movie is going to be actor id so entity framework. Once you do that, it will know that if I see actor ID, that is a link to do with the actor at the act itself. And also movies fall into categories you know, these are called genres or categories. So a movie could be action, could be horror, could be multiple, could be one. So many movies would fall into many genres. So underneath horror, there could be many movies and many, many movies that could also be tied to horror. So I'm going to bring in here another entity called genre which is not yet created I'll make it nullable and I'll call this genre. All right. Get and set and I'll go ahead and create this genre in the entities so go ahead and create the genre and make it public right. So for many to many , what happens if I if I just put genre here, I'm saying one, but if I put the word list here, entity framework will know that a movie belongs to many genres So I'll go to the genre itself. And in the genre you're going to have a genre ID. Obviously, to to know the specific genre. And also besides that, you want to have the genre name. So I'm going to bring a prop prop name and default that two string dot empty. But since this is a many to many relationship , so I also have to have a list here of movie here and I'm making it nullable OK now we said biographies still empty. We said a biography should have a bio Id so should have a bio ID and you want to have a description of a bio description of that bio that talks about that that actor. And since this is one to one, you also need to have here the the actor or the actor object here. So it so it knows that this is one to one. So it gets set over there. And also since it's one to one, you need to bring in the concept of an actor ID so prop int actor ID, there we go. And this is default this see strings dot empty. So let me go one more time of our entity so that you understand the relationships because that is very, very, very vital if you are to understand entity framework. So how are we doing our relationships we're saying an actor can have only one biography so you will see that we put the biography there, we put the biography object there. We are saying an actor can fall into many movies, can act many movies. That's why you're seeing a list of movies. So entity framework is going to know that at this juncture it will be a list of movies. Right? Then we're saying a genre can fall into multiple movies and a movie can have multiple genres but one actor can act in one move in that movie. Like you can have the same actor twice in one movie. That's not possible. So that's what we're saying here. Now, you see that for the case of one to one here, which is like the actor and the biography, it's going to be, well, we're going to use a foreign key for the sake of one too many here. We're going to use the foreign key, which would be the actor ID, in this case, let me just remove that All right. But when it comes to movies and genres, these are many to many So we need to create what we call it's kind of a weak entity. So so what entity framework will do, it'll create a table called movie genre and that movie genre is going to have the movie ID and the genre ID. So there would be another table. I want you to know this thing so that when we create the database, you understand how these things work. All right. So now we have our entities. We are saying that these are our entities. These are what will make up our movie management system, what is our next order of business? our next oder of business is now to create what we call a data context. So this this repository will be implemented using entity framework core So we need to bring in entity framework core. Now, there's a concept of what we call a context. A context is specific to entity framework. So context is going to give you a window through which you access a database. So you have your SQL Server database somewhere could be on your cloud, could be on your laptop, would be on a server which is locally hosted and you've got your API somewhere. You need to talk to that database. It will talk to the context so the context will give you access to things in the database. So here we're going to create that context and we're going to use that context. Now, the question is this is the domain. We're saying the domain only has the business logic. So it means for you to talk the database. As per our design, you need to talk to the data access layer, but for you to use entity framework core you have to bring in the entity framework core things. So you're going to right click on your data access class library and you're going to manage nuget packages once you get there, you're going to go to browse and you're going to type entity framework core. Entity framework core. All right. So you're going to get the entity framework core, make sure it's seven and install that and what else might we need you will need to have. The SQL Server coz we're going to use the SQL Server library, I mean database or that that one is needed and maybe tools so install that so we have brought into the framework core into our data access layer. Now we want access to that window. Give us an access through which we can access the database so our next order of business is to right click on the data access. lets create a folder We're going to call that folder context then within that folder we are going to create a class, we're going to call that class movie management DB context that will be used to talk to it database. So movie management DB context, OK, so there is a reason why we brought in entity framework because we want to use its its functionality to talk to the database. So we're going to inherit what we call it DB context, which is an entity framework core implementation. So this know, this DB context will give this class our access to whatever features we have in our database to run our migrations, to talk to a database and what have you. All right. So for you to access this, this context, you need to have a constructor and this constructor takes in what we call a DB context options. All right, so DB context options and this just takes in the name of your class and you're going to give it the options. And I'm going to show you this as we're as we're proceeding. And then this is going to have you're going to give it the base and the base. It's going to have the options, right? Like so now OK they're you have it and we just increase the font a little bit so that everybody can see even on mobile devices. So we're saying this is our context. But mind you, at this juncture, we have no database anywhere. We're going to use what we call code first approach. So we're going to use our code to create our database. We're going to use our entities to create our database. So this means that the database context needs to register, needs to understand what are the entities I need to build a database. So this is where we're going to declare our entities. So you want to do prop, we're going to use what we call a DB set. So DB set we want to give it our entities. Our first one was what was actor? So we have an actor so now, there isn't any link between these two. So I want you to pay attention here. Actor is in another assembly called domain, but we want to use it there. So it will say it doesn't exist because it doesn't know. But if I get control Dot, it will bring this add reference to a domain. If you click that and it means you have reference that that class library as a as a dependency rather as a project reference. So this table, we want to call it actors. All right. We're going to do the same for DB set for our movie. And we've got movie, then we've got prop to be set, we've got biography. We're going to call the biographies then we have prop DB set, and this is going to be our genre and we can call it as genres all right. Again, let me minimize that a bit and pretty much get some real estate over here. So what are we saying within the context? We have these four entities we want you to make note of this, four entities. OK, now I'm going to add one more thing because sometimes you want to start with some data. So we're going to seed some data and just put in data that we want to begin with now this is a function that when you override and overriding in in programing is the function does what it does. But when you override it, you tell it to do more than what it does. So this is what we call on model creating this one. So if we override this on, we're creating we're saying when you're creating this models please also do this certain thing. So that's what override means in programing. So we want you as you're creating to also populate may be I'm going to focus on the actors and movies table for the interest of time. Otherwise this videois going to be so long. So what you would do is you get the model built over there. So you're going to say model builder. All right. dot entity what entity you want to play with I want to play with actor entity, what functionality. So they have this what we call extension methods I'm going to use has data so this enables you to to put in data. So we're going to say has data. And then here we're going to say, give us a new actor object all right? And it has an ID. Just give an ID of one class first name. We're going to give it Chuck and the last name is going to be if you guessed it Norris And I could just add so I've left the movies and the biography on purpose because those are nullable and they're not really essential for you to have an actor and actor could be there without any movies. So this one's going to be two. It's going to be three. This is going to be could be Jane Doe It's fine. And we could have Jean Claude van Damme, right? So those are entities and other entities that I want to play with is going to be model builder. model builder model builder dot entity now i want the movies entity. So now you have to remember that the movies are linked to actors by the actor ID. So whenever you're creating a movie and that movie needs to have an actor ID because otherwise it's going to crash, we're using a foreign key. So I just to want you to note that it has data. OK, then I want to do this and I want to close it that then I'm going to say, give me give me a new movie, right? The ID of the movie could be one. Then you've got the movie name is Could be wakanda forever and then you're going to have description box office. We're coming again. Actor Id is very very crucial Actor ID . I want to give it one. OK, if that doesn't exist, it's going to crash. So I'm going to copy this and do it four times cause I'm going to put one actor twice. So I show you the one to many relationship. So this ID is going to be two. You could have the same Wakanda Forever movie and the other actor could be or the number two right then we could have another movie with ID 3. This movie could be Black Panther, or it could just be Spiderman. Spiderman oh, skyscrapers. Be warned. And this is acted by the first act as well. And then I'm going to have it last movie and this is going to be ID 4 could be The Matrix blue or red pill. Then this could go to actor number three. All right. So we're saying when you're creating that model, please add this data with you. So we have officially been able to set up our context. Now it knows now the next order of business you need to connect, OK, your context to a database. All right. So we're going to go to the API because the API by default, it comes with what we call the dependency injection container, which is here. So I don't really want to dive deep into that. Otherwise, we're going to waste alot of time and we're going to go out of scope. If you want to see that I've got videos or if you want to see how you can add dependency injection within a class library comment and we'll get to it. So we want to have a string a connection string to point where our database is going to reside. So where do your database reside? OK, so we'll do that in the movie management .API class if we go to the application, the JSON there, we can go and create our connection string. OK, there it is. So connection strings and within that we want to have a movie connection now to avoid you installing SQL Server management studio to it. I mean SQL Server on your PC and bring all the complexities. Microsoft visual studio comes with what we call a SQL Server Express. So we're going to use that. So you are going to have a data source and the data source would be the local DB. So call this local DB local DB slash Microsoft SQL Server, SQL Local DB Local Local DB then you're going to have we want to put a semicolon over there. Then we're going to have an initial catalog. It's just a fancy name for your database name. This name is going to be code unparalleled movie DB right? Then we're going to put a four colon with a semicolon rather than you're going to have integrated security, integrated security. This will just give you access to your database without any aunthetication as long as you're on Windows. So that is going to be true. So we're saying that when we run our migration we want you to use our local database and call that database, CUMovieDB and enable us to go there without any authentication to the sql server itself so once you've done this, the next order of business is to add to add entity framework to the dependency injection container so in 10 seconds, what's dependency injection? Every system has things that it'll depend on. These are called services. For instance, if you look at the API, it depends on a service called ADD controllers all the controllers we use. It's what it depends. It also depends on what we call swagger, which was in the browser. So these are what are called dependencies. Now, instead of you adding them all over the place, microsoft have creates what we call a dependency injection container that enables you to have one place to register that dependency. And throughout your application, all you're going to do is you just going to use that dependency somewhere with entity framework core here instead of us bring it in every field, we going to use our database, we're going to register it as a service in our container and we're just going to reference it through that container. All right. So we are going to use into the framework in this API. It's a dependency, so we're going to register that as a service. But before we do that, since it's entity framework, we might, as we also bring in a few things to do with entity framework. So we're going to need to install three packages for one, install the entity framework core itself to install the entity framework core itself and there it is. So we're going to install that and then we're going to install what we call the tools and you're going to install what we call design. So this will enable you to add those dependencies. So this is your dependency injection container. It's very simple. All right. So we want to bring in a dependency for entity framework. So this is where you build. So all dependencies must come before the build otherwise it will crash. So I'm going to it says add services to your container. So I'm going to add entity framework identity framework there. So for you to add a dependency, there's this thing that you're putting in for the builder. So you're going to call that builder dot on the services. You want to add something there. So we're going to add a DB context. So whats the DB context in. In our case, it's this one which we built. It's called what? Movie Management DB. So it'll take that now here you will see that the moment you take the moment you call this DB, it takes in an options menu and it get you give it what's needed. So I want you to pay attention. Once you've done that, it needs that option. So you're going to give that option. All right, so options, options. Then you're going to say options, then we're going to use a dot use you use sql server or you use sql server and for some reason bring the context. So again, because we're calling this from another assembly, we have to bring the reference and I'm saying to use it SQL server All right. Don't use SQL Server and here and want to bring in builder dot configuration dot get connection strings then I'm going to give it the name of the connection string. Now I see that this is not going anywhere. So that's going to mean one thing like something we haven't. OK, using entity framework core. Perfect. And here we're going to give it the name which we brought into our movie connection. So let me just put that and explain all right. So I was saying on the builder service on the services, add a context. So let our system know that we're using the context. And the context is movie movie management and in options, give it we're going to use SQL Server and it needs to know what sort of connection to going to use. We're saying go to the builder in the configurations, get the connection strings. So by default, entity framework supports connection string. So when it gets here, it'll see the word connections, things and then it'll go inside. And in the attempt to get the connection string provided, you give it a name which is move a connection. So it'll be able now to know that's where the database is so we have managed to create our context, create our entities. Now let's go ahead and create what we call let's create a database so we want around what we call database migrations so you're going to head over to tools and then go to a Nugget package manager and select the package manager console. But I want you to be to be to be careful here where you're going to run your migration because you might run into an error. You see that by default it defaults to API, but we want our database to be accessed using the data access. That's where our context is. So I want you to change this and make that data access. Then I'm going to put the word add migration then you're going to call this creating DB, right? And Press Enter. Something interesting is going to happen once you do this you're going to see a folder called migrations being created here. All right. And I want you to go and look closely at the what's been created. OK, so it's saying there are two methods. There's the up method and there is the down method. Right? So we are saying in the up method create for us a table called actors so that there is a table called actors It's saying these are the columns this is the primary key go and create for us, a table called genres. These are the two items. Thus the primary key create for us a table called what biographies. Now you see something interesting here. You see that the actor IDs now there, but that IDs now what one key to what table the principle table is actors. So you have link to biography to one actor right? Again you see a table called movies but the movies is linked what you see this actor all right. Again, since movies and genres as I said, they're weak entities. They're going to create a table called genre movie, which would just be the primary key would just be those two primary keys of those two subsequent tables. Then I've got migration builder dot insert data. So here it's insert in this data this and that and that is creating indexes. Now it's saying if you drop the if you undo the migration, it's going to drop all this table that's created. So our next order of business now would be to create the database. So this would be just going to type update hyphen database so this will go out of its way and it's going to create for you a database and you see done so or it was doing here it was running what SQL queries. So they have it. A database has been created. So how do we check that out? Database has been created. So our database name has to be CUMovieDB now if you go to view and select SQL Server Object Explorer then underneath the SQL Server we're going to see the local DB there this one. Then you're going to go to databases, you will see that, CUmovieDB has been created and if you go there, you will see that the tables also have been created. They area plus one table which use the migration histories. So this just keeps track of your migrations. Now our next order of business now is to actually implement the generic pattern so what you do normally is you're going to create a repository pattern for each and every entity which becomes problematic if they're like four And in general you have like hundreds of entities in any system. So are you going to have hundred repository pattern that becomes in that becomes a problem. So we want to say, OK, whatever belongs to the CRUD create, read, update and delete. At least we can just put that as as something that's generic. And once we do that, something as generic it will be easier for us to apply that on each and every entity. So we said the domain is responsible for logic that that access is responsible for us talking to the actual database. OK, so for our entire logic to talk to the database is going to be in our domain. So domain we're going to create a folder and we're going to call that folder repository. And when you the domain doesn't take the database, it's about access and you'll see that as we go. So created a folder called repository, and within that we're going to create an interface and we're going to call that interface and an interface. It's going to be an I generic repository. OK, so this one is what we now. We are going to define all of our common data access methods and they're going to be in this generic. So so a generic in general in C-sharp is it's like you're using a class that you have no idea what you're going to use. You could have a function that has it takes in the parameter an integer. So that function knows that every single time it's going to get an integer. But when we use generics, we just say this could be a class and handle that class. All right. That's the whole concept. It gives you the flexibility. It means you can just give it any entity and say, Go and just give me or that entity that's what the generic repository affords us with. So it means we're going to give it an argument called T. OK, so T that means whatever you're going to give, but since we want T to be a class, we want it to be explicitly a class, we're going to say make sure that this t is a class. So we're saying this interface takes in any class you give it, you don't have to know the class beforehand. Hence the word generic all right, then we're going to say so I want you to, to, to, to make sense of t so when I get get by id int ID, so it's saying when given the I'd return the t, just give the t whatever the t would be, it could be the actor it could be the biography. Right? So we're going generally here, OK, this is a skill. I think every developer should have especially generics. Then we're going to have an IEnumerable of t get all So whenever we just call this, give us whenever you give me something, whenever you are implementing a generic and you give me a class, get all of that, then we're going to have our next order of business. It's going to have it's going to be an IEnumerable. Sometimes we want to have the flexibility of not just of giving it our own, of giving it our own expression. OK, so we're going to say enable us to give us our own expression. All right. So expression and this expression is going to take a func T and putting in a predicate. OK, so we're saying sometimes if if we want to give a predicate let's say, a lambda function, it should be able to get it lambda and find that's specific we should be able to to add an entity, right? So we should be able to add an entity and we should be able to also add multiple entities. Should there be the need. So you should be able to add the range of given entities so this could be any number of entities. It should be able to do that. You should be also able to remove an entity. You should be also able to remove a range of entities. So we should be able to remove range given an IEnumerable of entities. All right. So these are what we think they're generic to application. So we should be able to get by an ID should be able to get all we should be able to get by a predicate. That could be an expression we should be able to add should be we should we should be able to add multiple we should be able to remove and we should also be able to remove multiple. All right. So this is now our generic, our next order of business. Now is to now create an interface for each and every each and every entity we have. All right. Because you might want to extend. So if you want to extend and it's got to just bring in those, uh, individual repositories. And also, if you look at the SOLID principles, interface segregation principle, it says whatever interface you have, it should be specific to that functionality. So interface should not be fat where by one interface has several things. But if it's an integration with actors, let's focus on this actor. So we're going to create interfaces for each specific entity. So I'm going to start with actor repository an going to create an Iactor repository, if you guessed it, congratulations So it's going to be an I actor repository or an actor repository like. So make it public. OK, but since we want this repository to have access to everything that's in the generic, we are going to inherit from the generic. OK, so and we are going to have an I generic repository but this generic repository wants you to give it a class So since this is an actor repository or then the class I'm going to give it is going to be an actor all right. Control dot All right. So now whenever I use this, this, this repository, have access to everything that this one has and here I can actually add more of my interface So I'm going to do the same for biography, genre and movie. OK, so create a new item interface. I movie repository and we're going to make that public public. And you're going to I should be I movie, shouldn't be a small letter right there. You name that to avoid issues. And this one is going to inherit from the I Generic repository. It's a movie. Give it a movie object and proceed for the genre new item to interface I Genre interface I Genre repositories Repository make that public and let that inherit from the I generic and give it a genre. Give it a genre class and finally to one for the biography. So add item and this is for the I biography repository repository enter again make that public I generic and give it the biography we have all of this ready to be used when necessary. So we're going to use what we call a unit of work. So this is just going to represent a single entity, a single instance of an application. So to avoid adding all of these dependencies to our dependency injection container, we're going to bring it a unit of work and unit of work, all it does is it is going to get a single transaction and do it and you see how that works in practical sense. So within the repository I want you to create another interface called the I Unit of Work. So go there and call it the . See, I Unit of Work OK? I'm just going to make it public and we want to dispose some stuff. So we're just bringing the I disposable here. So this just manages unused resources. So what do we need to be? What do we need in here? So we're going to have the I actor repository we want to call that the actor repository. OK, and we are going to have a get on it then we're going to have the I movie repository. Sorry about that. I movie repository. I movie repository I movie repository of repository and then get that and we're going to have the, I Genre repository I generic genre. So make sure you don't confuse those two. So I genre repository genre repository and just get that finally, we're going to have the I biography repository, biography repository and get that and know something I'm going to add, it's going to be int save. So Entity Framework There's something to do to save it. OK, so now we're saying when we use our I unit of work, it's going to give us access to all of this repositories. So whenever we use this, it'll be a window to our, our repositories, right? So now we have we have set our contract defined that our generic repository that its going to have this four Now we have to make an actual implementation of how you expect these guys to talk to a database. So we say the domain just has the logic, but actually implementation will be in the data access. So I'm going to go to the data access and create a class i mean a folder there Their call that folder implementation, implementation, implementation. So then within that, I want you to create a class called it generic repository, so a generic repository like so all right. So this class will implement the I generic repository. So I want us to implement that like so. So this is what is going to happen. But for you to implement this, you have to give it a T, so I'm going to give it a T and instead, again, where the T is a class T is class and you see it's already complaining it's saying implement the interface. So I'm going to click this and say implement interface. So if this is going to bring in and I wonder where that error is coming from, I generic repository give me a t where T is class where T is a class all right. When you wonder what is going on, you need to give it over there because if you want implement that it emits of a T, OK, so now we have to, we have to now go ahead and implement those. But remember, for you to talk to a database in entity framework you need to have the context. So we need to bring our context here and inject it using dependency injection of the constructor. So it means you are going to have a constructor. So ctor gives you a constructor right? Then we want this has what we call a context like so. So I'm going to place control dot and bring in the field and I'm going to make this underscore remove that So for you to talk to a database, you need a context. So if in this generic repository implementation want to talk to a database, then we need to have a context that's just a way entity framework does it. That's it. So there is a context. OK, so now let us proceed OK. So for you to add an entity, you're going to get the context and then just set the T and ass the entity That's what you need. All right. So it means anything that's given be an actor, whatever, what once you call this, then that's going to do for you to add a range which are multiple. Then you're going to get the context again. So they're going to say context dot set dot ass range to the entities. All right. For you to find an expression, you're going to say, OK, get me the context then set. Then just find me the predicate. Right? And I'm seeing the set of error. So I'm going to bring here we're close. So you're saying set that and what you set that since you're returning, then return it for me there. All right. And for you to get all what you need to do is return return the context dot set the set of t all right. Then just to list to list and they have it for you to get by ID. And then you need to return return the context. All right. dot set it on the T, so set on T then once you set that you could use find or first or default first or default, whatever whatever you prefer instead, of course, I will give you a warning to say it could be null but that can be handled. And for you to remove something, you're going to get the context and you're going to set set on T and dot remove the entity. And for you remove the range could be similar with that one on top. Get the context dot set set on t and remove range and you're want to remove the range and I just want to get that. So at this juncture all we have done is we're saying this is a generic repository if one wants add so it's very, very simple because this would be enough for everything, for all CRUD operations So instead of you having and I actor repository that handles all the crud an I movie that handles all the crud for the movie, this would suffice. The only time I use and I actor repository would just be if there's something that is specific to that use case and we're going to see one of them. So now we have we have implemented our generic repository the next course of business. Now we'll do to to now implement the context in each individual, in each individual repositories. Right. So here we have the actor, the, the biography the I Genre and now we're going to create them also because you might want to use them. So we're going to create also the I actor repository so I'm going to add a class there we are still in the data access because that's where we are talking to the data. So I'm going to have an actor repository here repository like so I'm going to make it public. And you want the I actor repository to inherit from the what generic repository, which is what have been implemented. And it needs a class a class will be actor like, so our class will be actor. Also, there's something we want to implement that we implement the I actor repository. I actor repository all right. When you're seeing an error that we want to fix that, then we are going to have a constructor ctor because the constructor now needs to be the movie DB context. So you're going to say movie DB context, context context, like so and then you're going to give it to the base as well cause you inherited from that base that business to get the context as well like so. So you've done it for the movie. So you're saying whenever I call actor repository, give it the context and give give it to the base it's parent into the context as well. So we're going to do the same for the other three for the genre So I want you to add add a class, you want to call it movie repository. Repository like so make it public and generic repository. Give it a movie. Give it a movie. Like so and also get it from a I movie repository. I movie repository. And here the constructor the constructor takes in and movie DB context called context and pass it to the base as well. Pass the context you're done with that and you're going to do one for genre call that general repository. So genre repository repository genre repository. Make that public that public. And this is a repository we're going to give it a genre and what are error we getting? Give it a genre then give it a genre an I Genre repository like so, and you're going to bring in your constructor and they're going to give it the movie Db Context to be context context. And the same goes to the base as well. Give it the context and I wonder why. Because we put generic supposed to be genre like. So then I want to finally for the biography so biography biography repository enter make that public and generic repository, I'm giving it a biography and the I biography repository. Then you're bringing it to your ctor Then have the movie DB context called Context called context and the same should go to your base context all right. So what we're saying here is whatever you want to do, implementations are going to be here. So it may look like a lot of work, but you want to do this once in every project and whenever you're adding it becomes very, very simple. So I want you to look to think long term on this one. Don't just think of Now, now, now, now, now, now, now. OK, so the last thing for us to implement is obviously the unit of work. So I want you to go to implementations and add a class call that unit of work like so. And this is going to be public, public, public. And it will inherit from the I unit of work. Right? So for you to use this you need constructor, that constructor takes the movie DB context called context. And we just close this up a little bit, call it context. And there's some things that you would want to know OK. So if you if you go to your I Unit of work, you will see that there were things that we had put in the I repositories and whatnot. These are the ones that you need to have here. So I'm going to bring in a public I actor repository call that actor. OK, so get and set it's I unit of work, just make the set public private rather. Then you can proceed to do one for public I movie repository call it movie gets set private and public biography repository for that biography and do that and finally do it for public I Genre repository genre and generic giving the headache I genre respitory Sorry call that genre and gets it public so. Oh OK. And then we have we had a method called save and also since it's disposable we are going to call one called dispose so I want you do to go down here and say public int save. So whenever you call the save method it's going to save because in entity framework if you just call the add it just add to the context but it does not reflect into the database. So you have to call a set method. So here you're going to return the context all right. So I want to bring in the context first pretty much like that so in that context, you want to go context dot save changes. So what that will do then you could also have a disposal method just to help you dispose, things public void into dispose and what do you do here? Just get the context. Just get the context. Get the context and dispose it. So whenever we call the unit of work, there have things that we want to to to implement things I want to to, to call So whenever I see the word actor here as I I repository the question is, it's what do you want to call subsequently? So whenever I see the word actor there you are calling an actual implementation of what that actor repository to which we have created that class and that class needs a context in its constructor. All right. The same goes for movie. Whenever I'm calling the movie, then I want you to call the movie or whenever I'm calling the genre and call the genre repository or whenever I'm calling the biography, then calling call. OK, so whenever I call this, which is a repository over here, give me the actual implementation of the class, cause you're going to call a context. All right. And it looks like we have something that's missing. I don't know what that is. I mean, just do this and implement that interface. So, genre I actor repository I actor repository So I think what it wants here it's actor this doesn't really make sense to me. I actor repository to react repository uh, why is it the case just a minute. I actor repository just the actor there I wonder why it's tripping I wonder why it is tripping I got the unit of work So this is because I had used this so I'm going to use actor there and here I'm going to use movie. So this structure to save you from possible mistakes and genre and call this biography. OK, so, so I should be able to be able to go through without an error. alright I know this video as long I know, but stay with me to the end. It's going to be worth it in the end. So now we talked of the concept of dependency injection. And if you go to our API, we had put in the entity framework core there. So for us to use the unit of work in one place and to avoid putting it everywhere, we also have to put it into the dependency injection container. So I'm going to put it in a dependency injection container. I'm going to say builder dot services dot add transient. Well, just a state. So a transient, I'm going to call this an I unit of work so whenever I see the I unit of work, I want you to use the unit of work, OK? implementation like so. So we have registered our dependency over there. so we are saying whenever you see the word I unit of work, go call me that class, the actual implementation of the class. Now, our next order of business now is just to create a controller to get all access and see if that unit of work is going to really help us now. So I want you to go to controllers here and create add controller. Make sure it's an API controller. we are going to use an empy one I'm going to call this actors controller enter. So our first order of business there is to see if that works. So I want you to go here and the first one is to be get request but before we do bring in the get request for us to use now this I Unit of Work which we have put here would just inject it into our controller. So let's inject that first so ctor and bring in an I unit of work here call it unit of work OK? And as a field like so and then here they're going to have something like that. So there you go. Now we're going to see public action result get you're going to say var items from repo repository is equal to get me the unit of work dot and or actor in that actor they should be they get all function like that and once you do that you could just return return an OK actors from repo now you might look like you've done a lot of work but I could tell you that if we had to have 17 more entities tomorrow I don't have to create for each and every one OK so let's go and try to set this one out. I'm going to use the I Express and let's go in run that and see what we get in the browser. So it would look this way and that's the endpoint. And if I'm going to try it out and execute see there I have it. I have all the actors that I had there and I didn't really code a repository for the actors and to show you that that's actually possible, I to actually change here and I'll get actors and say, I want to get all movies, OK, and I could run that and if I get here, try it or this should get me all the movies, you see. So this gets me all of the movies. And I didn't have to create a repository pattern for the movie for the actor and just one of those generic. So now you've seen where one can get all actors All right, congratulations. The next thing would be, how do I now extend? How do I extend for instance, somebody wants to get actors in movies, for instance. This maybe is not what you could use in your in your it's not maybe in your in your repository, but you want to bring in actors, for instance. So what can you do to extend this repository so what you would do is this if I want to get actors with with their movies, I'm going to go to the I actor repository because that's where it all begins. So I want to get let's at a specific functionality to do something for instance So I will get here in this repository and then I'm going to bring it in your function. I say I enumerable this returns actor. Let's get actors with movies, for instance, get actors with movies like so. So I have brought in a new maybe this is because on there so I have brought in a new I wonder why the blue is coming I have brought in a new extension to my repository and this is just specific to the actor, to the actor repository and from there, once you call it in, you are in your repository or you have to go here and actually implement it. And you see it's giving you an error. It says, I want you to implement that. So click it and it says they have it here. I want you to implement that. So you could say that. OK, fine. I will say var result of actors with movies, for instance, with movies is equal to and here you also going to learn something that might just save your career. I would say context. So get me the context give me the context dot get me actors, OK? But also in that actors, I want you to include movies so u is equal to U dot movie then to list get it to list like so and I wonder what's happening here it's saying inaccessible due to its protection. Let me go to actor repository. It should be something that the movie actor repository did we protect something from access through is not due to its protection due to its protection have I locked up the context or is one way to find out ok ok a public and just go to the actor repository actor repository. So there we have it. We have the context there. So we're saying get me actors and include movie. So yeah so here entity framework knows it will link those links when I help you and I just return a movie and there you have you have a new functionality over there. OK, now if I go back to my controller, I could add another one call. call it httpget and I would just say this one should be slash movies, for instance. Then I could say I would just copy this to rename it. Then I would come here and get get with movies. All right. Then once I once I do that. All right. So now you're going to say unit of work dot actors. Dot actors and movies, which is which is that and let us try to test that out and see and if I execute that and boom, unfortunately I end up with an error it says a possible object cycle was detected. All right. So we need to fix that. We need to fix that. So we're seeing it's saying that a possible object detected. So the way we fix that is with interest of time, you are going to go to the dependency injection container and you're going to ignore the cycles. OK, so if this code works, you add MVC add JSON options and then you're saying as you're serializing the reference handler, ignore any any cycle. So I'm going to stop that and I'm going to start that again. And once that happens, I could just try it out again. And this time around, it's able to get me Chuck Norris, within wakanda forever using Spiderman. So I see one too many is working the biography that doesn't exist. Jane doe is in one movie, van damme is in one movie. And so they have it. You are able to just just make a general, give it whatever, give it and it gets back. So if your application is going to increase in time, it's going to increase with entities. You have no need to and all you're doing is add an interface for it if you do any special cases. If not, then you're just going to use whatever is there. Now, I know that there's a lot of things I could do here. We could bring in the post to put the request, but if I do that, it would be a very, very long video. This could be a course on its own, but I hope with this information you could implement this on your applications and it could save you a lot of time. So if you be me, this far thank you very much. I do appreciate that you could share comment like and subscribe and if you want to be part of the process, you could sign up for them for the newsletter or you could be a patreon and support this free content that I intend to be putting out whenever I find time. Thank you very much. And do have a blessed day.
Info
Channel: Code Unparalleled
Views: 12,657
Rating: undefined out of 5
Keywords: generic repository C#, generic repository c# ef core, generic repository, dotnet core, api, azure api management, api management best practices, unit of work, microsoft mvp, design pattern, interface, entity framework, entity framework core, crud operation using generic, unit of work repository pattern, repository pattern, .net 7, clean code, SOLID principles
Id: xdibesoH8zE
Channel Id: undefined
Length: 71min 29sec (4289 seconds)
Published: Mon Dec 12 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.