Question

I often see code that uses the repository pattern to abstract the ORM. Why is this done? Isn't the ORM already an abstraction and acts as a repository itself?

Is there a big difference between

public class EmployeeRepo 
{
    GetById(int id) { //Access ORM here };
}

Consuming data:

public class MyController{
    private EmployeeRepo = _Repo = new EmployeeRepo();

    public ActionResult ShowEmployee(int id)
    {
        var emp = _Repo.GetById(id);
        //Versus
        var emp = ORM.Where(e => e.Id == id);

        return View(emp);
    }
}

Why should I go through the work of recreating what the ORM is already giving me?

Was it helpful?

Solution

I often see code that uses the repository pattern to abstract the ORM.

That's not needed in 99.(9)% of projects. Programmers seems to be over the moon by the fact they can create yet another abstraction over abstraction.

Why should I go through the work of recreating what the ORM is already giving me?

You should not do that, in fact, you create more problems, to name a few:

  • Has customer explicitly requested the feature to switch easily between ORMs? Really? Have you got a budget for this?
  • You ready to introduce test coverage for your abstraction, you have time and money for this
  • Have you got logging framework in place?
  • Have you consider design time to figure out common API that you can support? What about caching, sharding, load distribution, stored procedures, triggers?
  • Are you prepared to spend time to upgrade to a new version for several ORMs, are you ready to fix breaking changes?

What is better, is to use interfaces/base classes from the ORM itself, thus you can test and mock it easily.

OTHER TIPS

I know it's an old question, but subject is quite interesting to speak about.

I agree that it's easier to use ORM directly and may be it is the right thing to do in simple projects.

But if you are developing long-living complex system, direct dependency on ORM in your business logic means that you depend on that ORM in thousand places. This will inevitably create problems in future due to breaking changes in that ORM or simply because you decided to do something other way.

So, abstracting ORM is not so much about ability to switch ORM easily, it's more about decoupling your project from external dependency(probability of breaking changes in popular ORMs is high enough due to their complexity and continuous development). Plus, having such a decoupled architecture you will get nice testability of your project as a bonus.

If you don't want to do that abstraction by yourself, there are projects(e.g. Antler) around that could help you with that. Of course that would mean that you will depend on that frameworks in turn, but such frameworks take responsibility for dealing with different ORMs(and breaking changes in that ORMs) providing you abstractions and unified syntax that practically will never be changed.

Often this is the result of overengineering, but in the case that you may SWITCH ORMs, it is best to have your ORM encapsulated in a class whose contract AKA public/internal methods you control. This way, you can simply modify your class (or inject a different one if programmed to an interface) to switch ORMs. Otherwise, you must de-implement the direct ORM calls from all of your code and re-implement new calls in its place, which could be hundreds to thousands of lines of churn, depending on the complexity of your project.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top