Understanding the Repository Pattern in C#

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
In today's video, we'll talk about the repository  pattern. We will learn the benefits of using it   and how to implement it. We will use c# and  asp.net but the topic is relevant to any   programming language. My name is Pat, if you are  new here consider subscribing. Let's get into it.   Allow me to introduce this small application  that helps me manage a book library, I can add   a new book by providing a title, the author,  a category, and the date of the publication   of the book. if I click on the create button the  book is saved in a database. I also have a section   to manage authors and another one to manage  different book categories. This application was   created with Asp.net MVC, Entity Framework Core as  the data access layer, and SQLite as the database.   Let's take a look at the structure of the  project, we have controllers, models, views,   and so on, a typical MVC application. As you have  seen in the demo, the application is working,   however, it faces three problems that we  will discuss, problem number: 1 tie coupling All the controllers receive a book context  as a dependency in the constructor,   they use the context to retrieve or change data  in the database, the context object is specific   to entity framework, if one day we choose to use  another product like Dapper or NHibernate for   instance, we won't need it anymore, that means  we will have to go in every places the context   is used and replace it with some new code, that  can lead to introducing bugs in the application.   So, tie coupling makes it hard to change the  code. Let's talk about the second problem.   Problem number 2: duplication. When we need to  insert a new book, we have to select an author   from a list, the book controller gets a  list of author sorted by the last name   in order to display them in a drop-down list,  the author's controller also gets the same data   in order to display them in the author view, when  using the context straight into the controller,   we easily end up with duplicate code. Imagine if  we need some transformation on the author list,   we will have to go to each location where  the list is used in order to update the code.   Duplication makes it hard to change the code.  Let's talk about the last problem, if we want   to test the books controller, for instance,  we will have a problem because the controller   depends on the context object, that means we will  perform real operations against the database,   that's something you don't want to do when  testing, you want the controller to depend   on some abstraction so when testing you can mark  the abstraction. Those were the three problems   with the current state of the application. How to  change the code to make it less couple, reusable,   and testable? the answer is the repository  pattern. The repository is a layer that will   sit between the controller and the data access  layer, the controller will no longer depend on   the data access layer but instead on a repository  interface. Usually, you create a repository per   entity, we have three entities, we will create  three repositories. All repositories will inherit   from the same interface because they all need the  same method. Let's start by creating a generic   interface, we create a folder named repositories  then we had an interface called IRepository,   this repository has two generic types  T1 and T2, T1 has a constraint that   says that the type must be a class, like book,  category or author. T2 is the type of primary   key that will be used in some method like get by  id or delete. Let's add all the methods we need.   "GetAll" will fetch all data, if the repository  is used with book as a T1 parameter then this   will fetch all the books, "GetById" will  retrieve a single record given its id,   "Create" we insert a record in the  database, "Delete" will remove a record. and "Save" will apply changes to the database. Now, let's add a concrete implementation  of the repository. In the repositories folder, we   add a new class called book repository, this class  implements the IRepository interface, the first   parameter is the book type because a repository  will manage books, and the second is int which is   the type of our primary key. The repository uses  the book context to communicate with the database Each method use the DbSet to perform operations  against the database, let's look at the "GetAll"   method, for instance, I used the "ToListAsync"  method on the DbSet property to fetch all data,   and I load related data by using the  include method. In the "GetById",   we use the "FindAsync" method on the DbSet to  retrieve a single book. In the insert method,   we use the "AddAsync" and give a book as a  parameter to insert it in a database. In the   "Delete" method, we first retrieve the book  given its id, if it's found, we delete it.   And finally, in the "Save" method,  we persist changes to the database,   this method will be invoked after an insert  or a delete. I am going to create the category   repository and the author repository, they follow  the same pattern so I see you when I'm done. The repositories are created, so let's  register them with the dependency injection   system so we can inject them into the  controllers. In the Startup class,   let's update the "ConfigureServices"  method, we register the repositories   using the "AddScope" method, this means  that there will be an instance per request. Now, let's refactor the BooksController,  the goal here is to replace each usage   of the context with a repository. We  inject the repositories through the constructor, in the Index method for  instance, instead of fetching books   using the DbContext, we use the book repository. We do the same in the Create method We refactor also the Delete method In the method that populates the author list, we  use the "GetAll" method from the AuthorRepository   to retrieve all authors and in the  method that populates the category list,   we use the "GetAll" method from the  CategoryRepository to retrieve all categories. Let's test the application  to see if it's still working Yes, it's still working,  let's see if I can add a book The book has been saved to the database, now  I'm going to replace the DbContext in the   AuthorController and the CategoriesController,  so they can use the repository instead,   the process is the same as in BooksController,  so i see you after the refactoring. The refactoring is done let's test the app again.   It's still working, but now, the controllers  use a repository instead of the DbContext. This tutorial stops here. We learn how the  repository pattern makes the code easy to change,   less coupled, and testable. Despite all  the benefits we get from the pattern,   it adds a layer of complexity, use  the pattern when it makes sense   if you work on a tiny project for  instance maybe you don't need it.   If you enjoyed this tutorial, feel free to like  the video, drop a comment in the comment section,   and subscribe to the channel so you don't miss  future videos. Thanks for watching, see you soon.
Info
Channel: Tech With Pat
Views: 21,359
Rating: undefined out of 5
Keywords: .net core web api, asp.net core web api, c# repository pattern, design patterns c#, repository pattern, repository pattern c#, repository pattern in c#, web api tutorial c#
Id: BcQzZ97-mWU
Channel Id: undefined
Length: 10min 25sec (625 seconds)
Published: Wed Feb 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.