I am implementing a website using MVC3, Entity Framework 4.1 and Repositoty pattern, Unit of work principle. But I am facing a big problem while implementing this.

I have developed a static ObjectContext class. This class is used across all the repositories so unit of work pattern is followed. I have e.g. ICustomer, IProduct repositories. I use specifically only one repository in a controller and that too is injected using NInject.

Since object context class is static and IProduct, ICustomer have parameterised constructor which accepts the objectContext class, these two will share the same ObjectContext instance.

When the execution is single threaded everything goes fine, but in multi-threading I get an unhandled exception, because of one repository closing the connection which was being used by other. I think if I make ObjectContext class not-static then this will solve the problem(Not tested yet) but then Unit of Work will not be observed.

3 Answers
3

This is actually even worse than what you think. The ObjectContext class is not thread safe so even if you manage to get what you think is good synchronization, (without actually locking) you will still be throwing exceptions all the time in a multi-user environment.

The ADO.NET team recommends using a new ObjectContext every time you plan on querying the database. How else could anyone separate their data access classes from each other if this weren't the case?

I think if I make ObjectContext class not-static then this will solve the problem(Not tested yet) but then Unit of Work will not be observed.

Not true at all. The unit of work pattern has nothing to do with having a single repository for an entire application--otherwise, every entity framework tutorial would start you off by showing you how to create your static ObjectContext.

It simply means that if you can't commit the unit of work, the entire commit will be backed out and the entire commit must succeed for it to be successful; it's a single logical transaction.

If you need to keep objects around for the life of the application, look into caching them in a data structure other than an ObjectContext.

"using a new ObjectContext every time you plan on querying the database" is utterly impractical because a transaction cannot span multiple ObjectContexts. You want an ObjectContext for each unit of work.
–
qesFeb 3 '12 at 5:08

What you want is to instantiate one ObjectContext per web request, regardless of how many different database accesses might be required by that request. And you don't want to share it with any other web requests, or else you'll get your multithreading issues.

The approach I take is based on this blog post: "LINQ-to-SQL: the multi-tier story" by Steve Sanderson. Yes, it's about LINQ-to-SQL, not Entity Framework, but the same approach can be taken. Where he talks about LINQ-to-SQL DataContexts, just think EF ObjectContexts.

The approach you're currently taking is what he describes as "Story two: DataContext per application", and you've discovered the problems he talks about, namely to do with thread safety. You want to be moving towards what he calls "Story three: DataContext per unit-of-work (i.e. per request)", which involves creating one ObjectContext per web request and storing it in HttpContext.Current.Items, whose lifespan is that of a web request, and is private to that request.

Since you're already using dependency injection, you'll definitely want to read on to the final section "Stop! That’s still not good enough" where he explains how to break the dependency on HttpContext.Current using some simple inversion of control.

Use reference counting on the connection (and any other shared state which needs special clean up after use).

Whenever an object begins using the connection, increment the reference count. When the object is finished, decrement the count. When the count reaches zero, close the connection.

You will want to use a lock to protect the reference count and the connection open / close logic. There are a few race conditions around connection open / close which will cause problems, otherwise.

More generally, you're going to have to worry about synchronization on any state which is shared amongst multiple threads. If you keep this design, you need to get in the habit of looking up whether or not classes / functions are thread safe, and adding locks to protect anything which isn't, or which you aren't sure about. If you have multiple synchronization primitives, you will need to start worrying about acquisition order, and the possibility of deadlock.

This is one of the huge drawbacks of anything static or otherwise shared in a multithreaded application. Synchronization is really easy to screw up, and leads to difficult-to-reproduce-and-diagnose bugs. Ensure that you consider this in your evaluation of your design against other designs which don't require shared state.