Dmitry Sikorsky

Using the Unit of Work and Repository patterns with the Entity Framework Core

Hi! Let’s discuss why it is (or might be) still a good idea to use the Unit of Work and Repository patterns with the Entity Framework Core, while it already implements these patterns itself.

I heard from the different developers many times that it was a bad idea to have the custom UoW and Repository implementations on top of the EF, because they are useless and redundant since EF itself implements them. Yes, it is correct, EF does implement these patterns. But let’s look at the small example in context of the team work:

This code looks nice and returns adult cats sorted by name. But what if you need to get these cats in the different places of your application? You will have to copy it again and again. What if (sometimes in the future) conditions of the adult cats selection will be changed (for example, eight-years-old cats will be considered as adults too)? You will have to find all the places where this code is used and change it (and the standard Find/Replace tools are almost useless in this case because you can’t search by method name or something like this). Of course, you can miss something, and you will have 2 different algorithms for the same logic. Or, for example, you work in a small team, you are responsible for the statistics part, and now you have to display a list of the adult cats. To fix this task you have to look at the database structure, to understand which properties and conditions should be used etc. I think in real life you will have to contact data layer developer and ask him for advice. Again, in a small team it is not so big deal. But assume that we talk about some real-life statistics report generation with multiple joins, includes etc. How can you know how to build optimal query if you have no idea about database structure, indexes etc.

Now let’s look at another code sample:

Isn’t it much, much better?

Now a database layer guy (or a girl) can write optimized methods that cover all the use-cases your software product needs. They all have obvious names and parameter lists. They all can be tested and changed in one place when logic needs to be changed. And your team can be easily split by the responsibilities.

Somebody might ask why don’t we just write extension method for the IQueriable? Yes, we could. But in this case the situation can get even worse, especially when adding some new developer in an existing project. In this case developer can use both options: either write LINQ query himself or use an extension method (which might exist in a different namespace). Then, we will have the situation when the same logic is implemented by extension methods and custom queries at the same time.

Also, Service layer might be an option. But in the most applications I saw (simple ones), every service method just called corresponding repository one, without any special logic. It means that the service layer was basically useless.

So, I really think that these 2 patterns are still very actual, they help to keep things simple, simplify modifying, testing, and maintaining of the data layer code, team work.

Here you can find some code sample (but it is a bit old, I have to update it): https://github.com/DmitrySikorsky/AspNetCoreStorage

Monday, August 20, 2018 by Dmitry Sikorsky