Share via


EF/ASP.NET - Should I use the Repository as a singleton?

Question

Sunday, August 1, 2010 9:26 PM

Hi everybody,

I'm working on an ASP.NET MVC2 application and my data layer is based on EF. I have a repository that serves all data objects to the business logic layer and all is working fine.

In Some scenarios I find myself passing data object instances from one object to another (usually as method parameters) and sometimes I get stuck with data object instances, which were loaded by different repository instances, and I cannot link between them since they are tracked by different DataContexts. I manage to solve it by having the "correct" repository instantiate those instances that were initially were instansiated by ther other repository. Gee.. I hope that was clear..

Anyway, after finding myself in this mess too many times and realising that all those re-instantiations cause additional db calls I think I should find a better solution and the one I think would be most suitable is to have the repository as a singleton and thus all data objects will be generated and tracked by the same DataContext.

Not sure if that's a good solution or if ther's a better one, so happy to hear your thoughts. My main questions/thoughts are:

  1. Technically speaking is there a problem implementing a Singleton repository?
  2. The DataContext will be a member in a static readonly repository, should I worry about threads?
  3. Since that's a web app then a singleton instance is shared among all users who are in the site now. How do you think it's best to avoid collisions and data integrity issues? Maybe I should maintain a collection of instances based on Session key or something else that could identify a specific user?

Happy to hear anything anyone feels he can contribute to this subject!

Thanks!

All replies (3)

Monday, August 2, 2010 12:35 PM ✅Answered

1. No. But usually the singleton is hardly tested

2. yep, about errors too. Please use a DataContext per "Unit of work"

3. read about "optimistic concurrency" and "pessimitic concurrency". Usually my approach is "last user wins" - is the easy way ;-)


Tuesday, August 3, 2010 2:15 AM ✅Answered

Hi,

I just realised that I can use HttpContenxt.Items collection for storing a repository instance for the whole request process. This means I instantiate once the repo and store it in the Items collection to be served to any object that needs it during the request cycle.

I think this will help me achieve what I need.

Thanks for your help and happy to hear any thoughts or comments.

Cheers,

D.


Tuesday, August 3, 2010 12:20 AM

Hi,

Thanks for the reply!

I tend to agree with everything except for the second item. The problem that I have revolving around the fact that different contexts created different data objects and this leads to situations where I cannot link between them since they belong to different contexts. Here's an example:

public void AddCar(Car c)
{
  this.Garage.Cars.Add(c);
}

Lets say that Garage and Car are data objects and that the garage and car were created by different repository instances we will have a problem executing this method since these data objects belong to different contexts.

If I use context per "unit of work" that's exactly when I get those problems, unless I either somehow manage to work in each request with the same repo instance or maybe I should attach each passed data object to the current context. Not sure what are the implications of attaching a data object to another context though..

Does this make sense??  :-)

Thanks.