Repository Pattern with C# and Entity Framework, Done Right | Mosh

Programming with Mosh · Beginner ·🛠️ AI Tools & Apps ·10y ago

Key Takeaways

This video demonstrates the Repository Pattern with C# and Entity Framework, showcasing how to decouple the application from persistence frameworks and minimize duplicate query logic. The video covers the benefits of the Repository Pattern, how to implement it with Entity Framework, and best practices for using it in a clean architecture.

Full Transcript

Okay, this is my favorite lecture in this course because there are so many blog posts and videos about repositories and many of them conflict with each other which made me confused about the repository pattern for a long time. So in this lecture I'm going to explain clearly what repository is and what it is not why and if we need it and address some of the misconceptions about repositories. So what is the repository pattern? I'm going to start with a definition from Martin Fowler's book patterns of enterprise application architecture. Repository mediates between the domain and data mapping layers acting like an in-memory collection of domain objects. I've highlighted in-memory collection in this phrase because that's the key here. So what are the benefits of the repository pattern? The first one again based on Martin Fowler's book is that it minimizes duplicate query logic. So imagine in a few different places in our application, we need to get the first five top selling courses in a given category. Without the repository pattern, we'll end up duplicating this query logic over and over in different places. In situations like this, we can encapsulate this logic in a repository and simply call a method like get top selling courses which takes two parameters, the category and the number of courses to return. So this is one benefit of the pattern. Another benefit of the repository pattern is that it decouples your application from persistence frameworks. In this case, entity framework. So in the future, if you decide to switch to a different persistence framework, you can do so with minimal impact on the rest of your application. Now the first argument that comes here is that some developers say, "But who would change the persistence framework of an application?" Well, let me tell you something. The fact that this does not happen very often is not because it's not desirable. It's because most of the time application architectures are so tangled and tightly coupled to any framework that it doesn't give us the freedom to change it. A while ago I read somewhere on a blog that on average every two years we get a new persistence framework and I think that's very true. First we had ADO.NET so we used SQL connection and SQL command to access the database. Then link to SQL came along but it didn't prove to be successful. Next entity framework version one arrived which had so many issues. Nearly at the same time in hibernet got popular. Then after four versions entity framework reached a stage that it was reasonable to be used in production but still at this point it had a heavy object model that was not testable. Then they introduced a new model DB context. Now they are working on version seven which is a complete rewrite and there are some breaking changes. Not to mention that along these lines we have had other persistence frameworks like Dapper OM light paoo and so on. So our persistent frameworks are constantly changing and evolving and if you want to have the freedom to explore a different persistence framework with minimal impact in your application that's when you should use the repository pattern. Now there is also another benefit with the repository pattern that some claim that it makes it easier to unit test your application but that's partially true and that's if you're using an older version of entity framework with object context and object set. The new DB context and DB set objects have interfaces that you can mock to unit test your applications. So you don't necessarily need the repository pattern to unit test your application. Now the theory behind what is the repository in practice in a nutshell. This is what your repository should look like. They should act like a collection of objects in memory. So we have methods to add or remove an object, get an object by ID, get all objects or find them using a predicate. Note that here we do not have a method called update. Because with collections in memory, if we want to update an object, we simply get it from the collection and change it. We don't tell the collection to update an object. And that's one of the areas that a lot of developers get wrong. A repository should not have the semantics of your database. It should be like a collection of objects in memory and shouldn't have methods like update and save. Now with this, the first question that pops into a lot of people's head, including myself a long time ago, is if the repository acts as a collection of objects in memory, how are we going to save these objects and changes to them to the database? That's when the unit of work pattern comes into the picture. A unit of work maintains a list of objects affected by a business transaction and coordinates the writing out of changes. And this is where things get interesting. Some developers argue that both the repository and unit of work patterns are already implemented in entity framework and there's no need to recreate them as this would lead to unnecessary complexity. Let's see if this argument is valid. So the argument says that DB set has a collection-like interface. So it has methods like add, remove, find, wear. And as you see, it doesn't have methods like update and save. So perfect. Also, the argument claims that the DB context acts as the unit of work. It keeps track of changes in the objects and coordinates the writing out of changes. As you see here, a DB context has references to one or more DB sets and the save method is actually implemented here. So again, it makes sense because as I explained, the save method should not be in the repository. Plus chances are in a business transaction we may work with more than one repository. So that's the reason the save method should be in the unit of work. So it will coordinate persisting changes across multiple repositories in one transaction. So on the surface yes entity framework DB sets and DB context indeed look like repositories and unit of work. But there is a hidden problem here with the implementation of these patterns in entity framework. Let's review the benefits of the repository pattern again and see if our DB sets satisfy the definition of repositories. So a repository minimizes duplicate query logic and I showed you an example of this before. Now the problem with DB set and link extension methods implemented on them is that they return I queryable and this means if you want to get top selling courses you will end up repeating these few lines in a few different places in your application. In fact in one of the projects I worked on recently this was exactly the case. So DB context was everywhere and we had long fat queries repeated over and over. What you see here is actually a very simple example. I've seen worse. So the implementation of DBS set does not really help with minimizing duplicate query logic. Yes, you can argue that we can use extension methods to encapsulate this logic into a method in a DBS set. And believe me, we had exactly this scenario in that project. In my opinion, this solution treats the symptoms, not the actual problem. Because even if you use extension methods, all the existing link extension methods on DB set still return I queryable and next time a developer joining your team is going to use them to write new queries. So in this case ideally we want a repository that has a method like get top selling courses and all this querying logic is encapsulated there. The DB context should be a private field in the repository and not exposed to the outside. It's the implementation detail. Now the second benefit of repository pattern is that it decouples your application from persistence frameworks. When you're using DB context and DBs directly in your application, your application is tightly coupled to entity framework. If you want to upgrade to a newer version of entity framework with a different model or switch to a different OM, you need to modify your application code directly. However, if all this is behind a repository and your application code relies on the repository to return the right data, it doesn't matter what is inside the repository. Today you can use any framework in a repository. Tomorrow you may decide for optimization reasons to replace it with store procedures. Your application code will not be affected in any way. It simply asks the repository to get the data and repository does its job. It doesn't matter what's inside the repository how it's done. Are we using store procedures? Are we using entity framework? Are we using object context or DB context or a different RM? It doesn't matter. So with all these in my opinion while DB sets and DB context in any framework do look like the implementation of the repository and unit of work they don't really bring the architectural benefit that we can get from these patterns. If you have not read about clean architecture I highly recommend you to look it up. Uncle Bob or Robert S. Arden has a beautiful post on the topic and my favorite line in that post is the architecture should be independent of frameworks. This allows you to use such frameworks as tools rather than having to cram your system into their limited constraints. So that's why using patterns like the repository pattern help you decouple from frameworks such as entity framework. Now the theory aside, I want you to think like an engineer. Be pragmatic. Keep it simple. My favorite quote is that simplicity is the ultimate sophistication. Just adhering to clean architecture principles and using all sorts of patterns doesn't necessarily make you a better coder. Neither does it improve the quality of your software. Not every application needs sophisticated architecture like this. A lot of times you might be building simple or proof of concept applications for a limited audience. Please don't do overgineering. A while ago I worked for 5 months on an application where its requirements were rapidly changing and there I didn't use any of the stuff I talked about in this lecture. I had no repositories, no clean architecture, no unit testing, not even dependency injection because we were not sure if the application would even make it to the production for financial and political reasons. And guess what? the application never made it to the production. So if I spent a lot of time adhering to all these architectural best practices, I had just wasted my time. It wouldn't bring any values. Some developers simply use patterns without really understanding the problem. And this way they feel good about themselves. My pragmatic suggestion to you is use patterns only when you need to. Don't use them as deodorants to make smelly code smell good. Now in the next lecture I will show you how to implement the repository and unit of work patterns with entity framework. I hope you enjoyed this lecture and thank you for watching. All right. Now let's see how we can implement the repository pattern with entity framework. First I'm going to show you a diagram of the interfaces and classes and then we'll explore the code. So to start with we need a repository interface. This interface is like the interface for a collection of objects in memory. So it has methods like add, remove, get, and find. Again, here we're not going to have update or save. Next, we're going to implement this interface in a class called repository. Inside this repository, we're going to have a DB context, a generic DB context. So what you see here is completely generic. It's got nothing to do with our application. We can reuse this interface and the concrete implementation of it in any applications. In context of our application Pluto, for each entity, we're going to have a repository. So for course entity, we're going to have an interface called I course repository. In this interface, we're going to define any operations specific to courses that are not in our generic repository. For example, we can have a method like get topselling courses or another method get courses with authors which uses eager loading to load the courses and their authors. So this is one of the key things here. Anything to do with eager loading or explicit loading is data access concern. Your application code, your business logic should not care how this is done. This is the implementation detail that should happen inside a repository. Your business logic layer, your services simply tell the repository give me courses and their authors and the repository works out how it should be done. Now here I course repository just declares the contract. So we need to implement it in a class like course repository. So in this diagram course repository derives from our generic repository because a lot of our data access code is similar but it also additionally implements I course repository interface. So it's going to have implementations for these two methods you see on the right side. Next unit of work. So we need an interface like I unit of work. This interface is specific to our application. So it's going to expose various repositories based on the entities we have in our application. For example, here we have two properties courses and authors. And the types are I course repository and I author repository respectively. And note that here we have a method called complete which indicates the end of a unit of work. We could call this save, but I personally prefer to call it complete because this is completion of a unit of work. Next, we need a class to implement that. So, we're going to call this unit of work. Now, let's flip over to Visual Studio and see all these interfaces and their implementations in action. I'm going to take you through every interface and their implementation, but you can also download all the source code in the supplementary materials of this lecture. Let's start with I repository. Okay, here's my I repository interface. Note that this is a generic interface where T entity is a class. Some developers like to have a marker interface like I entity and decorate their domain classes like course, author, tag, cover and so on with that interface. Then here you could say where t entity is I entity. But I personally don't quite like marker interfaces because it's like fooling yourself. It doesn't bring any value. Anyway, here we have three groups of methods. The first group is for finding objects. The second group is for adding objects and the third group is for removing objects. So the first method get receives an ID and returns an entity with that ID. We also have get all which returns all objects and find which takes a predicate. This predicate is an expression an expression of funk. So this means we can use a lambda expression to filter objects. Exactly the same way we use the wear method with link. Next we have add which adds one object to the repository and add range which adds a list of objects. And similarly we have remove and remove range. So as you see this repository interface is like a collection. It doesn't have methods like update or save. Now let's look at its implementation. So here is my generic implementation of the repository. Note that it takes a DB context in constructor and this is generic. It's got nothing to do with our application. So it's not Pluto context. I have declared this as protected because in derived classes like course repository or author repository I'm going to use it. Now look at get all this method returns I innumerable. It doesn't return I queryable. And that's the key thing here. Your repositories should not return I queryable because this can give the wrong impression to the upper layers like services or controllers that they can use this I queryable to build queries which is completely against the idea of using a repository in the first place. Your repositories should encapsulate your queries so you do not repeat them. So here in get all I simply called two list to return an I innumerable. Now the implementation of other methods like find, add, add add range is pretty similar to using a normal DB context to adding objects or removing them. So nothing special here. Again, you can download the source code and study it on your own. So note that this I repository and its implementation are completely generic. They got nothing to do with our application. Now let's take a look at a custom repository. So I'm going to show you I course repository. So this interface derives from our generic repository interface. So it's going to inherit all those generic operations like add, add at add at add range, remove, get, and so on. But it also declares two additional operations. Get topselling courses and get courses with authors. Again, note that both these methods return I innumerable. So we're going to execute the query inside the repository and return a list of objects to the client. Now let's take a look at the implementation of this interface. So this class course repository derives from our generic repository because we don't want to repeat all that code for adding removing and getting objects from the repository. So it inherits from repository of course and also implements I course repository. So here's the implementation of the methods in this interface. Now get top selling courses does not really have the actual implementation of getting top selling courses. All I'm doing here for simplicity is ordering courses by their full price and getting the first few most expensive courses. So this is not really top selling but you got the idea. Now look at this method get courses with authors. This method uses eager loading to load courses and their authors. So we start with courses then include authors then order by skip and take. This is for paging because we have supplied a page index and a page size. So this is another technique that you can use with repositories. Some developers think they have to use I queryable so that they can apply filtering in the upper layers like services or controllers. But your filtering for pages shouldn't happen in those layers. It's data access code and should happen inside your repositories. So the way to do that is by passing two parameters here. Page index and page size. We could optionally give this a default value to make calling this method easier. Like page size is 10 by default. Now here I have declared a property for simplicity. This property is of type Pluto context. So all I'm doing is casting the context that we are inheriting from the generic repository the base of this class. We're casting that to Pluto context. Otherwise in every method here I had to repeat this code. Cast the context first and then get access to the courses DB set. Now let's take a look at the unit of work. So here's my IU unit of work interface. Note that it inherits from I disposable and exposes two repositories course repository and author repository. And note that both these are interfaces. This is for testability. So we can mock this interface and this properties in our unit test. And here's my complete method. Let's take a look at the implementation. So this unit of work as I said is specific to our application. So it receives Pluto context in the constructor and store it in a private field here. And this is the interesting part. It uses the same context to initialize both repositories. So the client of unit work will instantiate a Pluto context and then we'll use this context across all repositories. Next here is the implementation of the properties courses and authors which were declared in our interface. The complete method simply calls the save changes on the context. And here is the implementation of the dispose method. So we simply dispose the context. Now how can we use all these interfaces and classes al together in our application. Let me show you an example. So in a console application we simply have this using block and inside this block we initialize a unit of work with a new Pluto context. This is not how you do it in ASP.N MVC or WPF applications there. We don't really use the using block. This is just for console applications. I will show you how to use this later in ASP.NET MVC and WPF. Okay. Now let's go through three examples. I'm going to get a course with ID one. So I start with unit of work exactly like how we start with DB context. Now here we have authors and courses again similar to DB context. The difference is instead of DB set these properties are repositories and these repositories as I explained are generic. Unlike the DB set they know nothing about entity framework. So this way we decouple our application from entity framework. So unitwork.courses dot get here's the ID that's it another example I want to get all courses with their authors. So unit of work courses and because this is I course repository here we have those additional methods that were declared in I course repository. So get courses with authors first page and the page size is let's say four. So everything you learned in this course about DB context and DB set and cing applies here. The only difference is you're working with different interfaces that are not part of entity framework. Let's go through one more example. Earlier in the last section where I talked about removing objects, you saw that in order to remove an author and his courses because we didn't have cascade delete, we had to remove the courses first in order to remove the author. So I want to remove an author first. I need to get it. Unit of work authors do get author with courses. So this method was declared in I author repository is specific to our application. Author with ID1. Now I need to delete all his courses. So, unit of work.courses remove range author.courses. Now, I can delete the author himself. Unit of work that authors remove author. And finally, I need to complete my unit of work. So, changes will be saved to the database. So, unit of work.complete. That's how you should use repository and unit of work. So again, download the source code, study it on your own, and if you have any questions, feel free to post them in the discussions area. In the next lecture, I will show you how to structure your application. I hope you enjoy this lecture, and thank you for watching. [Music]

Original Description

🔥Get the COMPLETE Entity Framework course (80% OFF - LIMITED TIME): http://bit.ly/2rZAgrD Want to learn more from me? Check out my these links: Courses: https://codewithmosh.com Blog: https://www.programmingwithmosh.com/ Facebook: https://www.facebook.com/programmingwithmosh Twitter: https://twitter.com/moshhamedani Confused about the repository pattern? This tutorial explains it all. There are many tutorials about the repository pattern and many of them are conflicting. If you've been confused about the proper way to implement the repository and unit of work patterns with Entity Framework, this video is for you. 00:00 What is the Repository Pattern? 00:47 Benefits of the Repository Pattern 03:50 Repository in a Nutshell 04:47 What is the Unit of Work Pattern? 05:00 Does Entity Framework Really Implement Repository and Unit of Work Patterns? 09:31 Clean Architecture 11:43 Implementing the Repository Pattern 14:09 Implementing the Unit of Work Pattern 15:09 Repository and Unit of Work Patterns in Code 22:49 Example of Repository and Unit of Work Patterns Download the source code for this video here: http://programmingwithmosh.com/wp-content/uploads/2015/10/RepositoryPattern.zip And here are some YouTube videos of mine you might be interested in: Event and Delegates in C# https://youtu.be/jQgwEsJISy0?list=PLTjRvDozrdlz3_FPXwb6lX_HoGXa09Yef Generics https://youtu.be/gyal6TbgmSU?list=PLTjRvDozrdlz3_FPXwb6lX_HoGXa09Yef
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from Programming with Mosh · Programming with Mosh · 21 of 60

1 6 Visual Studio Tips to Increase Your Productivity | Mosh
6 Visual Studio Tips to Increase Your Productivity | Mosh
Programming with Mosh
2 Visual Studio Keyboard Shortcuts that Speed Up Debugging Applications | Mosh
Visual Studio Keyboard Shortcuts that Speed Up Debugging Applications | Mosh
Programming with Mosh
3 Backbone.js Tutorial Part 2 - Backbone.js Models: Working with Model Attributes
Backbone.js Tutorial Part 2 - Backbone.js Models: Working with Model Attributes
Programming with Mosh
4 Backbone.js Tutorial Part 3 - Backbone.js Models: Model Validation
Backbone.js Tutorial Part 3 - Backbone.js Models: Model Validation
Programming with Mosh
5 Backbone.js Tutorial Part 4 - Backbone.js Models: Model Inheritance
Backbone.js Tutorial Part 4 - Backbone.js Models: Model Inheritance
Programming with Mosh
6 Backbone.js Tutorial Part 1 - Backbone.js Models: Creating Models
Backbone.js Tutorial Part 1 - Backbone.js Models: Creating Models
Programming with Mosh
7 Backbone.js Tutorial Part 5 - Backbone.js Models: Syncing Models with the Server
Backbone.js Tutorial Part 5 - Backbone.js Models: Syncing Models with the Server
Programming with Mosh
8 Backbone.js Tutorial Part 6 - Backbone.js Collections: Creating Collections
Backbone.js Tutorial Part 6 - Backbone.js Collections: Creating Collections
Programming with Mosh
9 Backbone.js Tutorial Part 7 - Backbone.js Collections: Working with Collections
Backbone.js Tutorial Part 7 - Backbone.js Collections: Working with Collections
Programming with Mosh
10 Backbone.js Tutorial Part 8 - Backbone.js Collections: Fetching Collections from the Server
Backbone.js Tutorial Part 8 - Backbone.js Collections: Fetching Collections from the Server
Programming with Mosh
11 Backbone.js Tutorial Part 9 - Backbone.js Views: Creating Views
Backbone.js Tutorial Part 9 - Backbone.js Views: Creating Views
Programming with Mosh
12 Backbone.js Tutorial Part 10 - Backbone.js Views: Passing Data to Views
Backbone.js Tutorial Part 10 - Backbone.js Views: Passing Data to Views
Programming with Mosh
13 Backbone.js Tutorial Part 11 - Backbone.js Views: Handling the DOM Events
Backbone.js Tutorial Part 11 - Backbone.js Views: Handling the DOM Events
Programming with Mosh
14 Backbone.js Tutorial Part 12 - Backbone.js Views: Handling the Model Events
Backbone.js Tutorial Part 12 - Backbone.js Views: Handling the Model Events
Programming with Mosh
15 Backbone.js Tutorial Part 13 - Backbone.js Views: Handling Collection Events
Backbone.js Tutorial Part 13 - Backbone.js Views: Handling Collection Events
Programming with Mosh
16 Backbone.js Tutorial Part 14 - Backbone.js Views: Templating
Backbone.js Tutorial Part 14 - Backbone.js Views: Templating
Programming with Mosh
17 Clean Code: Learn to write clean, maintainable and robust code
Clean Code: Learn to write clean, maintainable and robust code
Programming with Mosh
18 C# Events and Delegates Made Simple | Mosh
C# Events and Delegates Made Simple | Mosh
Programming with Mosh
19 C# Generics Tutorial: Whats and Whys | Mosh
C# Generics Tutorial: Whats and Whys | Mosh
Programming with Mosh
20 Debugging C# Code in Visual Studio | Mosh
Debugging C# Code in Visual Studio | Mosh
Programming with Mosh
Repository Pattern with C# and Entity Framework, Done Right | Mosh
Repository Pattern with C# and Entity Framework, Done Right | Mosh
Programming with Mosh
22 Angular 2 Tutorial for Beginners: Learn Angular 2 from Scratch | Mosh
Angular 2 Tutorial for Beginners: Learn Angular 2 from Scratch | Mosh
Programming with Mosh
23 Architecture of Angular 2+ Apps
Architecture of Angular 2+ Apps
Programming with Mosh
24 Working with Components in Angular
Working with Components in Angular
Programming with Mosh
25 C# Tutorial For Beginners - Learn C# Basics in 1 Hour
C# Tutorial For Beginners - Learn C# Basics in 1 Hour
Programming with Mosh
26 Difference between Junior and Senior Developers
Difference between Junior and Senior Developers
Programming with Mosh
27 Step-by-step ASP.NET MVC Tutorial for Beginners | Mosh
Step-by-step ASP.NET MVC Tutorial for Beginners | Mosh
Programming with Mosh
28 [Pluralsight]: Become a Full-stack .NET Developer
[Pluralsight]: Become a Full-stack .NET Developer
Programming with Mosh
29 Xamarin Forms Tutorial: Build Native Mobile Apps with C#
Xamarin Forms Tutorial: Build Native Mobile Apps with C#
Programming with Mosh
30 Value Types and Reference Types in JavaScript
Value Types and Reference Types in JavaScript
Programming with Mosh
31 Using Redux in Angular 2+ Apps | Mosh
Using Redux in Angular 2+ Apps | Mosh
Programming with Mosh
32 Testing Angular 2+ Apps with Jasmine and Karma | Mosh
Testing Angular 2+ Apps with Jasmine and Karma | Mosh
Programming with Mosh
33 Profile and optimize your Angular 2 apps
Profile and optimize your Angular 2 apps
Programming with Mosh
34 Build a Real-world App with ASP.NET Core and Angular 2
Build a Real-world App with ASP.NET Core and Angular 2
Programming with Mosh
35 Entity Framework 6 Tutorial: Learn Entity Framework 6 from Scratch
Entity Framework 6 Tutorial: Learn Entity Framework 6 from Scratch
Programming with Mosh
36 Two-way Binding and ngModel in Angular 4
Two-way Binding and ngModel in Angular 4
Programming with Mosh
37 Udemy Live 2017: Teaching Tech Panel
Udemy Live 2017: Teaching Tech Panel
Programming with Mosh
38 Demo of An E-commerce App Built with Angular, Firebase and Bootstrap 4
Demo of An E-commerce App Built with Angular, Firebase and Bootstrap 4
Programming with Mosh
39 My Brand New Angular Course
My Brand New Angular Course
Programming with Mosh
40 TypeScript Tutorial - TypeScript for React - Learn TypeScript
TypeScript Tutorial - TypeScript for React - Learn TypeScript
Programming with Mosh
41 Access Modifiers in TypeScript
Access Modifiers in TypeScript
Programming with Mosh
42 TypeScript Interfaces
TypeScript Interfaces
Programming with Mosh
43 TypeScript Classes
TypeScript Classes
Programming with Mosh
44 TypeScript Constructors
TypeScript Constructors
Programming with Mosh
45 TypeScript Properties
TypeScript Properties
Programming with Mosh
46 Angular Tutorial for Beginners: Learn Angular & TypeScript
Angular Tutorial for Beginners: Learn Angular & TypeScript
Programming with Mosh
47 AngularJS vs Angular 2 vs Angular 4 | Mosh
AngularJS vs Angular 2 vs Angular 4 | Mosh
Programming with Mosh
48 Angular Material Tutorial | Mosh
Angular Material Tutorial | Mosh
Programming with Mosh
49 Angular Animations Tutorial | Mosh
Angular Animations Tutorial | Mosh
Programming with Mosh
50 Firebase in Angular Applications | Mosh
Firebase in Angular Applications | Mosh
Programming with Mosh
51 Deploying Angular Applications | Mosh
Deploying Angular Applications | Mosh
Programming with Mosh
52 Building Forms in Angular Apps | Mosh
Building Forms in Angular Apps | Mosh
Programming with Mosh
53 Directives in Angular Applications
Directives in Angular Applications
Programming with Mosh
54 Routing and Navigation in Angular | Mosh
Routing and Navigation in Angular | Mosh
Programming with Mosh
55 Angular 4 in 40 Minutes
Angular 4 in 40 Minutes
Programming with Mosh
56 [NEW COURSE] Unit Testing for C# Developers
[NEW COURSE] Unit Testing for C# Developers
Programming with Mosh
57 Unit Testing C# Code - Tutorial for Beginners
Unit Testing C# Code - Tutorial for Beginners
Programming with Mosh
58 C# Classes Tutorial | Mosh
C# Classes Tutorial | Mosh
Programming with Mosh
59 C# Object Initializers Tutorial
C# Object Initializers Tutorial
Programming with Mosh
60 C# Constructors Tutorial | Mosh
C# Constructors Tutorial | Mosh
Programming with Mosh

This video teaches how to implement the Repository Pattern with Entity Framework, decoupling the application from persistence frameworks and minimizing duplicate query logic. It covers best practices for using the Repository Pattern in a clean architecture and demonstrates how to create a generic repository class and implement a custom repository.

Key Takeaways
  1. Implement the Repository Pattern with Entity Framework
  2. Create a generic repository class
  3. Implement a custom repository that inherits from the generic repository
  4. Use eager loading to load related data
  5. Filter data in the repository for pages instead of in upper layers
  6. Pass page index and page size as parameters to data access code
  7. Inherit from I Disposable and expose two repositories
💡 The Repository Pattern is used to decouple the application from persistence frameworks and minimize duplicate query logic, making it easier to switch between different persistence frameworks and maintain a clean architecture.

Related AI Lessons

Chapters (10)

What is the Repository Pattern?
0:47 Benefits of the Repository Pattern
3:50 Repository in a Nutshell
4:47 What is the Unit of Work Pattern?
5:00 Does Entity Framework Really Implement Repository and Unit of Work Patterns?
9:31 Clean Architecture
11:43 Implementing the Repository Pattern
14:09 Implementing the Unit of Work Pattern
15:09 Repository and Unit of Work Patterns in Code
22:49 Example of Repository and Unit of Work Patterns
Up next
How to Open HPL Files (HP-GL Plotter)
File Extension Geeks
Watch →