Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dispose DbContext in MVC Controller, which way "better"?

In MVC 5, the scaffolding codes will have something like:

    public class MyController : Controller
{
    private MyContext db = new MyContext();

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }

otherwise, I need to have

using (var db = new MyContext())
{...}

in each action.

The codes look good, so I don't need to use using in each action. However, is this subject to preference of programmers, or such style has some advantage over using in each action that needs to use the dbcontext?

like image 976
ZZZ Avatar asked Nov 03 '14 05:11

ZZZ


People also ask

Should you dispose DbContext?

Don't dispose DbContext objects. Although the DbContext implements IDisposable , you shouldn't manually dispose it, nor should you wrap it in a using statement. DbContext manages its own lifetime; when your data access request is completed, DbContext will automatically close the database connection for you.

How do I dispose of DbContext EF core?

When the controller is being disposed, call dispose on your repository and that should dispose the context. If you are using a service layer and not talking to the repository directly from the controller, then call dispose on the service which will call dispose on repo which will dispose the context.

How does MVC know which controller to use?

Also, MVC relies heavily on reflection, which allows you to inspect types at runtime using strings. Reflection is used in many programming frameworks.


1 Answers

In terms of best practices, you should absolutely use the template scaffolded stuff and not mess with the using(){} pattern unless you have some really good overriding reason. Both solutions produce the same result, but both are not good solutions. The reason why the template has a single DbContext is to make it easier to test - heres an example:

public class SomeController : Controller
{
    private ApplicationDbContext db;

    public AccountController()
    {
        db = new ApplicationDbContext();
    }

    public AccountController(ApplicationDbContext context)
    {
        db = context;
    }
}

The first constructor with no arguments is that which is used in production and automatically creates a new db context based on the app config file. The second allows you to inject a mocked db context when you are doing unit testing.

At the end of the day, this question and my answer isn't really about disposing db contexts - it's about why the code template designers chose to take the approach they did and why it will help you. You should read more on unit testing.

like image 95
Ben Avatar answered Sep 22 '22 16:09

Ben