I'm using the Entity Framework for an ASP.NET Web Forms application and I'm wondering how I should deal with ObjectContext
and it's lifetime.
For example, I have an InviteService
class that manages invites such as creating and accepting invites. The class itself is in another project/namespace from the Web project.
An InviteUsers()
method creates Invite
entities for a list of users, calls a repository to save them to the database and mails each user an invite link.
The method is called from the Page
when a user clicks the invite button.
I would like to know how I should use the ObjectContext
- Instantiate a new
ObjectContext
on the Page on each Request, passing it as a parameter to the constructor of theInviteService
class and then disposing it in theRender
method. - Same as above but instead of setting it via the constructor, passing it along as a parameter to each method.
- Create a separate
Objectcontext
in each method with ausing
block.
Option one seems best to me based on the answer of Ladislav here: Entity Framework and Connection Pooling But option 3 seems valid as well since as far as I know, no new database connections are made because of connection pooling.
It is not unusual to create a single
ObjectContext
per web request. I do this in my web applications. However, IMO, the page should know nothing about theObjectContext
.Since you are already talking about injecting the context in the constructor of the service, take a look at dependency injection (if you aren't using that already). When you use a dependency injection container, you can let the container create that service for you and inject the object context in that container. The only thing your page has to do is request that service from the container (ideally, you would even let that service be injected in the constructor of that page, but this is not possible with web forms).
Your page would look like this:
In the startup path (Global.asax) of your application, you can configure the Dependency Injection framework like this:
In these examples I used the Simple Injector dependency injection container, although any DI container will do. The
RegisterPerWebRequest
is not part of the core library, but is available as (NuGet) extension package. The package ensures that yourObjectContext
is disposed when the web request ends.This might seem complex at first, but this way the web page doesn't have to worry at all about any details of creating and disposing an
ObjectContext
.Further, place the logic that executes a use case in a single class: a command. Let the command (or the system) ensure atomicness of that operation. Don't let the page be responsible for this, and don't commit on the end of the request, because at that point you won't know if it is even OK to call commit. No, let the command handle this itself. Here is an article about writing business commands.
This advice holds for ASP.NET MVC as well, although you should not call
Global.GetInstance<IMyService>()
inside the Controller's constructor, but simply use constructor injection (since MVC has great support for this) and use the MVC3 Integration package.Also take a look at this Stackoverflow question, which talks about choosing between a
IObjectContextFactory
or having aObjectContext
per request.