Search code examples
c#entity-frameworkdependency-injectionanti-patterns

Why inject the entire DbContext instead of just the necessary DbSets?


I've seen a lot of projects whether the entire DbContext is injected in a class:

public class MyClass
{
    public MyClass(MyDbContext context)
    {
        ...
    }
    
    public void DoStuff()
    {
         dbContext.MyTable.Select(x => x...)
    }
}

Why not do this:

public class MyClass
{
    public MyClass(DbSet<MyType> myTypes)
    {
        ...
    }
    
    public void DoStuff()
    {
         myTypes.Select(x => x...)
    }
}

I find #2 makes it more clear as to what data exactly the object needs to operate. It makes unit testing especially more clear as the dependencies are obvious from the constructor. Otherwise, you have to inspect the implementation of the method to find out what data it needs exactly so you can setup your test properly.

So why is #1 the norm?

(P.S. sorry for bad tags but it seems the tag system is broken atm)


Solution

  • Normally developers write unit tests to test business use cases and the data access layer should not contain any logic and that's why people use Repository Pattern to hide the implementation of the data access layer.

    Otherwise, you have to inspect the implementation of the method to find out what data it needs exactly so you can setup your test properly.

    MyDbContext and DbSet<MyType> are related to data access and when you try to implement unit tests for DoStuff method, you should not consider the implementation of query for writing test and the only thing you need is mocking MyDbContext or DbSet<MyType>. Also when use concrete class as a dependency, you violate Dependency Inversion Principle, and that is why you have to look at the implementation of DoStuff method to find out what data and where the data comes from.