Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

All of the below relates to a ASP.NET c# app. I have a Singleton Settings MemoryCache that reads values from database on first access and caches these, then invalidates them using SQL Service Broker message and re-reads as required.

For the purposes of standard controllers, i create my Db Context in a request scope. However, this obviously means that i can't use the same context in the Settings Cache class, since that is a singleton and we have a scope collision.

At the moment, i ended up with two db contexts - the Controllers get it via IoC container, whereas a Singleton just creates it's own.

However, i am not satisfied with this approach (mostly due to the way i feel about two contexts, the cache doesn't set anything on the db hence concurrency is not an issue as much).

What is a better way to do it?

share|improve this question
    
Why does the cache know about the database? Could you just cache the results of the DB call? Possibly doing so would allow you to use DI to create the class that sets up the cache with data. –  psr Jan 29 at 1:26
    
@psr the cache knows about the db cause i use SqlDependancy variant that allows the cache to be invalidated automatically when data in the db changes (using SQL Broker) –  zaitsman Jan 30 at 8:17
add comment

1 Answer

The DbContext is not thread safe so you should not use a singleton DbContext in an ASP.NET web app. A thread per request is created and you'll start getting exceptions as soon as multiple users begin using your application.

It sounds like you're wrapping the cache in another class that has its own DbContext. Why not just have that class take a DbContext in its constructor? Also, is there a reason you aren't using HttpContext.Current.Cache (Cache class)? That is the preferred way to Cache in ASP.NET (If you aren't using a 3rd party cache) and it will have the lifetime of the app domain. I'm fairly sure this solves all of your singleton and 2 DbContext issues.

According to Microsoft

The MemoryCache class is similar to the ASP.NET Cache class. The MemoryCache class has many properties and methods for accessing the cache that will be familiar to you if you have used the ASP.NET Cache class. The main differences between the Cache and MemoryCache classes are that the MemoryCache class has been changed to make it usable by .NET Framework applications that are not ASP.NET applications. For example, the MemoryCache class has no dependencies on the System.Web assembly. Another difference is that you can create multiple instances of the MemoryCache class for use in the same application and in the same AppDomain instance.

source

share|improve this answer
    
the first part of your message has puzzled me. Separating the DbContext and Cache problem - Should i or should i not create DbContext per request? –  zaitsman Dec 30 '13 at 0:16
1  
You should create a new DbContext per request. IIS/ASP.NET uses new threads to serve requests and the DbContext isn't thread safe. Even if you aren't explicitly creating new threads, your singleton DbContext will have multiple threads operating on it. If multiple users are using your website at the same time, you will run into issues. A static DbContext variable won't work. See these links : stackoverflow.com/questions/6126616/is-dbcontext-thread-safe stackoverflow.com/questions/1416351/… –  brian Dec 30 '13 at 0:21
    
i guess you misunderstood the question. The singleton in the picture is the SettingsCache class; the class creates and disposes of manually retained context when the data is read; the data is then stored in cache; there is no updates from this singleton class. The trigger for this, however, is the SqlDependency, created by the getter of the property. The dependency connection is maintained by .net and is not explicit. The dbcontexts that operate with the actual data via controller actions are managed in the HttpRequest scope, just as you suggested. –  zaitsman Dec 30 '13 at 1:04
    
@zaitsman: If the question has to be explained it's better to edit the question, so others don't have to search the comments. It's common in SO to have to edit the question before it's clear enough. –  david.pfx Mar 30 at 3:07
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.