Managing the Entity Framework ObjectContext instance lifetime in WCF and sharing it among repositories

As I pointed out in a previous post about using the Repository pattern in EF and WCF, it’s a bad practice when service operations manage the ObjectContext instance lifetime and have dependencies on it.

In this post I’m going to show you how to share the same ObjectContext among repositories as long as the service is activated (either PerCall or PerSession) and have the service totally agnostic of it.

The IDbContext interface can be used as a wrapper for the ObjectContext or even NHibernate’s ISession. The IDbContextManager will be used by the repositories to get an IDbContext instance.

To simplify things we can extend our existing ObjectContext class using a partial class that implements the IDbContext interface. In this case, since I’m using the same example as the previous post it should look like this:

So now we can use our repositories without having to worry how to give them an ObjectContext anymore. We simply have to supply an implementation of IDbContextManager. In this case, I’m going to implement a DbContextManager that will return the same IDbContext instance while the wcf service is activated in order to reuse it among repositories.

The idea here is to leverage the extensible object pattern implemented in wcf by providing our own extension object to the service’s InstanceContext. If you don’t know what this is I recommend reading this blog post for some background.

The first thing to do is to create the extension class. It will be used to “attach” an IDbContext instance to a wcf service’s InstanceContext.

To apply this IInstanceContextInitializer to the service we need a behavior. In this case, we want to use an IServiceBehavior. I’m calling it DbContextBehavior and I will also expose it as an attribute to simplify its usage.

This implementation works fine with EntityFramework because the generic TContext type represents an ObjectContext class and you can instantiate it with the new operator. For NHibernate we would have to tweak this class or even create a different one..I might write another post on how we can support both ORM’s here and still make it transparent to our service.

Now we can refactor the OrderService to leverage the DbContextBehavior we just created. Note that we don’t have any reference to the ObjectContext anymore. We simply care about using the repositories and if we had a CustomerRepository for example we could share the same ObjectContext among the repositories.

The IoC class is a singleton class I use that exposes an Inversion of Control container like Unity for example. Note that the commented constructor would be a recommended approach if we could have our service be resolved by the IoC container instead of the default way.

The following code is the what we need to wire up all the types that the IoC container needs to resolve:

In WCF RIA Services if your DomainService class derives from LinqToEntitiesDomainService you will have only one instance of your ObjectContext class available in your service, thus you can pass it directly to repositories. I think you don’t need to use this technique with RIA Services.

I’m working on a project that uses WCF RIA Services, Entity Framework and the Repository pattern as well. Soon I will post some examples which might interest you.

I will provide the source code for this example as soon as I can.

I’m thinking in creating a project at Google Code to host the source code of each blog post so everyone could access it with a SVN client (I use Tortoise).

I wrote it with EF v1. As far as managing the ObjectContext lifetime in WCF and sharing it among repositories, this technique should still work, although I haven’t tested.

What may not work is the implementation I’ve got for the base repository class. I should rewrite it soon, and I apologize for not having done it yet but free-time is something I’ve been lacking lately..

Anyway, the code is still hosted. Try using this link to see the files:

You don’t need to implement the IDisposable interface because the class that implements IDbContext already implements IDisposable. That class is your generated ObjectContext class from Entity Framework.
What I did was extend it by creating a partial class to abstract its use by implementing the IDbContext interface.

Manuel, I want to have different EFcontexts(EDMX files) in separate projects(libs) but share the same generic repository and Igenericreposistory and contextmanager from a separate project.
Is this what I should to ?
container.RegisterType<IDbContextManager,WcfDbContextManager>();

In fact you should register a WcfDbContextManager for each different ObjectContext class but notice that the interface IDbContextManager knows nothing of the ObjectContext so you can’t use dependency injection properly that way. Also note that the WcfDbContextManager class is generic, thus you cannot use it without specifying the generic argument which is an ObjectContext concrete class.

What you can do is create an IDbContextManager(TContext) interface that extends from IDbContextManager (just for type safety).

Then create a specific base repository class (that derives from EntityRepository(TEntity) ) for each of your ObjectContext’s and have its constructor depend on the IDbContextManager where TContext is the specific context for those repositories. Then call the base constructor passing the IDbContextManager(TContext) instance and it will work fine because it derives from IDbContextManager.

I haven’t tried this but that’s what I can think of at the moment. The only problem I’m seeing is that you cannot have the same service use more than one ObjectContext unless you modify the DbContextInstanceExtension to hold more than one IDbContext. For example, using an IDictionary where the string key is infered from the ObjectContext’s Type (that should work and still be transparent for the service).

I hope this helps. If not, I can try to sumarize all this info into c# code.

Hi Manuel,
I was wondering whether you had time to blog about WCF RIA Services, Entity Framework and the Repository pattern as you indicated in one of the comments here. I have not been able to locate it if you did blog about this aspect, and I would appreciate if you would point me to it.

I downloaded the source code from svn, but I have always got an error when called host.Open()

Service ‘MF.Services.OrderService’ has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.

The solution for your problem is to register a different manager for the IDbContext, since the one I provide depends on WCF’s OperationContext.Current and you were using it in a console app without WCF.