I’m building a layered application using Entity Framework code first approach with an mvc4 web application, separated mainly in Data, Services, and Web.
From my web I do this:
public void Foo() {
EntityService _svc = new EntityService();
Entity = _svc.FindById(1);
}
The service method looks like this:
private readonly MyContext _ctx = new MyContext();
public Entity FindById(long id) {
return _ctx.Entities.SingleOrDefault(q => q.EntityId == id);
}
The problem is when I need to use more than one service because each service will create it’s own context.
Trying to solve this I did something like this:
public class MyContext : DbContext {
private static MyContext _ctx;
public MyContext() : base("name=myConnectionString") { }
public static MyContext GetSharedInstance() {
return GetSharedInstance(false);
}
public static MyContext GetSharedInstance(bool renew) {
if(_ctx == null || renew)
_ctx = new MyContext();
return _ctx;
}
}
Changed my services as follows:
public class EntityService
{
private readonly MyContext _ctx;
public bool SharedContext { get; private set; }
public EntityService()
: this(false) { }
public EntityService(bool sharedContext)
: this(sharedContext, false) { }
public EntityService(bool sharedContext, bool renew)
{
SharedContext = sharedContext;
if (SharedContext)
_ctx = MyContext.GetInstance(renew);
else
_ctx = new MyContext();
}
}
Now if I want to share an instance of my context, I’d do something like this:
EntityService _entitySvc = new EntityService(true, true);
AnotherEntityService _anotherEntitySvc = new AnotherEntityService(true);
Is this, at least, a decent way to overcome this? I’ll appreciate any help provided. Thanks.
Never ever ever ever ever ever ever ever… ever… did I mention ever? I mean it. Never ever create a static data context. Never ever. Really. Can I stress this any more? Never. Don’t even think about it. Thinking about it will give you brain cancer.
This is one of the situations in which Dependency injection really shines. With Dependency injection, you can manage the lifetime of your data contexts and make them live for the lifetime of the request, rather than the lifetime of the app pool, as a static does.
To elaborate on why a shared context is bad. Not only is the context shared among your classes, but also among threads and requests. That means two users using the site at the same time will stomp all over each others data context, causing all kinds of problems. Data contexts are NOT thread safe, and they’re not concurrent safe.
If you want to share your data context with multiple objects, then you need to pass it in to those objects, either as part of a method call, or as a constructor argument.
I highly recommend doing this via Dependency Injection, however.