Managing the Context's Lifetime5:11 with James Churchill
We've aligned the beginnings of the context and controller class lifetimes, but we still need to align the end of the context's lifetime to the end of the controller's lifetime. Let's see how to do that by disposing our context when the controller is disposed.
To follow along committing your changes to this course, you'll need to fork the dotnet-comic-book-library-manager repo. Then you can clone, commit, and push your changes to your fork like this:
git clone <your-fork> cd dotnet-comic-book-library-manager git checkout tags/v2.4 -b managing-the-contexts-lifetime
F5- Start Debugging
F9- Set a breakpoint on the current line of code
F10- Step Over
Implementing a Dispose Method
For more information on how to implement the
Dispose method, see https://msdn.microsoft.com/en-us/library/fs2xkftw(v=vs.110).aspx.
Managing Entity Framework DbContext Lifetime in ASP.NET MVC
There are actually three ways to manage the lifetime of your database context.
- Dispose Pattern
- Dependency Injection Container
In the Treehouse Entity Framework Basics course, we used
using statements. While in this course, we used the Dispose pattern. In a future workshop, we'll introduce dependency injection.
For more information about how to use dependency injection to manage the lifetime of the database context, see this blog post from Dave Paquette:
Do You Always Have to Dispose Your Database Context?
In this course, we implemented the Dispose pattern in order to ensure that our database context was always properly disposed. But did we have to do that? As it turns out, it's not always necessary to call the
Dispose method on the database context object, but it's typically a good idea to do so. See this blog post from Jon Gallant for more information:
We've aligned the beginnings of the context and controller class lifetimes, 0:00 by instantiating an instance of the context class, 0:03 in the controller class constructor. 0:06 But we still need to align the end of the context's lifetime 0:08 to the end of the controller's lifetime. 0:12 We can do that, by disposing our context when the controller's disposed. 0:14 Let's take a moment to review, 0:19 why it's important to dispose of the context after you're done with it? 0:20 As we've seen in an earlier course, our context class inherits from 0:24 the EF DbContext class, which implements the IDisposable interface. 0:28 The IDisposable interface provides a mechanism for 0:33 releasing unmanaged resources, through its single method, Dispose. 0:36 Unmanaged resources need to be released or 0:41 cleaned up, in order to prevent memory leaks. 0:43 Applications that have memory leaks will gradually, over time, 0:46 consume more and more memory. 0:50 Which will cause the application to slow down, and 0:52 potentially even slow down the server that the application is hosted on. 0:55 When we use our context to persist or retrieve data from the database, 0:59 EF will open a connection to the database, which is an unmanaged resource. 1:03 By calling our context's Dispose method, which is inherited from the DBContext base 1:08 class, we're letting EF know, that the database connection can be closed. 1:13 Previously, we placed the instantiation of the context within a using statement. 1:18 In order to ensure that context isDispose method was called. 1:22 Now that we are instantiating the context within the controller's constructor, 1:26 it's no longer possible to use that approach. 1:29 Luckily, there is a way to explicitly dispose of the context. 1:32 As it turns out, 1:37 the controller base class implements the IDisposable interface. 1:38 There are a lot of interfaces here. 1:44 Let's scroll to the right a bit. 1:46 And here's the IDisposable interface. 1:51 This means, 1:54 that the controller base class includes a public nonvirtual Dispose method. 1:55 The public nonvirtual Dispose method is called by consumers of this type, 2:00 specifically in this case, 2:05 the MVC framework when it's done with the controller. 2:07 The public nonvirtual Dispose method in turn calls this protected 2:10 virtual Dispose method. 2:15 The protected virtual Dispose method is where all of the actual cleanup of managed 2:17 and unmanaged resources is done. 2:22 Since this method is marked with the virtual keyword, 2:25 we can override it in the comicBooks controller class. 2:28 That gives us the hook that we need in order to explicitly dispose our context. 2:31 Scroll down to the bottom of the comicBooks controller class, and 2:36 override the Dispose method. 2:40 Remember, typing override will prompt Visual Studio to display a list of methods 2:42 in the base class that are available to override. 2:47 We can then simply just select the method we want to override, and press enter. 2:51 In order to guard against the case, if the Dispose method is called more than once, 2:56 let's define a private field to track, 3:00 if the Dispose method has already been called. 3:03 Then, just inside of the Dispose method, 3:07 let's check the value of the disposed private field. 3:09 And if it's true, we can short circuit the method by immediately returning. 3:13 The context is a managed resource. 3:18 So we should only dispose it, if the disposing parameter value is true. 3:20 Following this pattern, prevents us from attempting to release managed resources 3:25 that may have already been reclaimed. 3:29 Then after disposing the context, we need to set the disposed private to true, 3:32 indicating that the Dispose method was called. 3:38 Let's test our changes. 3:41 Outside breakpoints, just inside of the Dispose method, 3:42 And the constructor. 3:51 And run the web app. 3:57 Here we are at our breakpoint, in the constructor. 4:03 So, our controller is being instantiated. 4:06 Press F5 to continue execution. 4:08 And here we are at our breakpoint in the Dispose method. 4:13 Now our controller is being disposed. 4:17 Press F10 to step down to the Dispose method call on the context. 4:20 And F10 again, to execute the method call. 4:30 Then F5, to continue execution again. 4:34 And here's our list of Comic Books. 4:38 The dispose pattern is a commonly misunderstood design pattern that is, 4:42 unfortunately, often implemented incorrectly. 4:46 For this reason, it's a good idea to always review Microsoft's official 4:49 documentation under MSDN website, when you need to implement the dispose pattern. 4:53 For more information about the dispose pattern, see the teacher's notes. 4:59 Now that we're properly handling the lifetime of our context, 5:03 let's move on to updating our controller to handle creates and updates. 5:07
You need to sign up for Treehouse in order to download course files.Sign up