Is there a way in .Net to switch out the Cache provider just like I would a membership provider, or role provider? I would like to keep the code untouched but switch to using a distributed cache like memcached or AppFabric.
All I am finding is how to switch out the output cache provider. This might be necessary, but it doesn't solve the issue of when Cache is called directly from within my code.
I've found many libraries and they abstract Cache behind an interface, but this would mean I have to go to every spot in my code and inject the new abstraction. Also I am using PLINQO, which internally uses Cache.
Is OutputCache the only thing I can switch out through configuration?
Thank you in advance.
You may take a look at the following presentation which explains the pre-.NET 4.0 state of caching and what .NET 4.0 brings in this respect. In .NET 4.0 the caching has been completely reworked into a separate assembly (System.Runtime.Caching) and rendered extensible. That's true for both object caching and page output caching. Unfortunately if you have current code that relies on the old Cache class this has to be changed as this class works with in-memory objects only.
Related
We have an environment with a vendor deployed application to several front ends on it. It makes heavy use of the ASP .Net storage (Session, Application, and Cache). Problem is with the load this environment quickly brings IIS to it's knees with the amount of data it's trying to keep in memory.
The solution we are trying to go with is to override the storage mechanism and implement our own. (Specifically a Redis server to manage the storage)
We have implemented their cache interface and set up Microsoft.Web.Redis.RedisSessionStateProvider in the web.config to manage the session. That part all works fine. The problem is that the caching inside the vendor application does not always use their provided interface. Decompiling the dll and examining dump files show that there are several instances of them directly calling (for example):
HttpContext.Current.Cache.Insert(...) and HttpContext.Current.Application[...] = ...
Is there any way we can override the HTTPContext* calls so that they'll use Redis to cache instead of the Asp .Net application storage?
When it is a "3rd" party which uses HttpContext.Current you probably have no chance to change that behavior.
Is this other application running within your context (do you control the app domain). Or is it a standalone application?
I once tried to change HttpContext.Current.Cache for unit testing and ended up mocking the whole HttpContext because it was so very internal somewhere in the Microsoft stack.
All this is pretty hard to do, not really recommended and can lead to all kinds of other errors.
In short, don't use HttpContext.Current.Cache. Use something you can inject.
In general, libraries should never use that static context.
It is much more flexible to have abstractions + DI for those kind of things...
For caching, you could use CacheManager for example.
I have a legacy application that is extensively using HttpContext.Cache...
This application is now suppose to move to Windows Azure (multi-role).
It will of course cause problems with cache going out of sync on different roles.
I was thinking about injecting (I'm using Autofac) my "AzureCacheWrapper" (wrapper on Microsoft.ApplicationServer.Caching.DataCache) into HttpContext.Cache so legacy application continues working but uses Azure cache instead?
Normally we should implement something like ICacheProvider but unfortunately there are some 3rd party DLLs that are using cache that we don't have access to (and don't know when 3rd party library is using Http cache)
I don't think cache provider can be configured through web.config (like OutputCaching) so the only solution seems to me to somehow inject my implementation into Add/Insert/Get methods on Runtime Cache.
Unfortunately because of .NET implementation of System.Web.Caching.Cache (sealed class) I don't think I can override HttpContextBase to return different cache or inject into System.Web.Caching.Cache itself...
Thanks for any help! :)
I think your application needs code/architectural change...
If you had your own class which handles getting and setting the cache, Which may easier now to change your code/architecture in one place.
If you are going to use Single role then no problem exist in your scinario. If possible you can run your webrole in ExtraLarge slot.
I'm building a site in Symfony 2.0 that has a fair amount of AJAX, which builds page content with data it gets from an API, like: http://mysite.com/api/pictures/list
Data is handled using Repositories, which are sometimes used in page code so that string of images you see might come from the controller using the PictureRepository, or via Ajax using the API which accesses the PictureRepository.
I'd like to use Memcached to ease the database load, but am not sure where to put the caching code. Is it best to cache the database result, or the API result? Or is the difference negligible? Having the memcached logic inside the Repository would mean writing the code once (regardless of whether it's accessed via the API or directly), but it seems like it would also make sense to avoid accessing the Repository whenever possible.
Thoughts?
My opinion is that memcached should be used for session storage.
For your purposes you should better think about using of Varnish as http cache.
After that, you can configure your application use ESI.
At least, that is how we do it in our applications ;)
I'm working on an MVC3 app and I've come across an issue with objects being cached unintentionally.
My code is creating objects from calls to a separate custom business logic dll.
This business logic dll gets data from a database.
After I change data in the database, I'm still seeing the old data, even after closing my browser and re-running the application. It's not a browser caching issue because I can see it when I'm debugging in the development environment.
In development, if I stop the asp.net development server, then re-run the app, I get the new data.
In IIS, if I restart the website, I get the new data.
Any idea why asp.net is caching and re-using these objects, even after they have gone out of scope?
The business logic dll does have some caching built into it, so maybe that's the main issue. In that case, I guess the question is whether there is some way I can tell asp.net to wipe out the objects once the session is over.
There's no caching by default in ASP.NET MVC3, at least no caching of data. Make sure your IIS settings are correct and you don't accidentally use the OutputCacheAttribute.
As for caching in the business layer: I've seen at least three caching-related problems in the last two days. Keep in mind: Caching is tricky, and so are static variables. If it's not necessary, don't do it. Caching is extremely powerful, but it's also dangerous. That is also true for the beforementioned OutputCacheAttribute.
It sounds to me like you're creating your data context statically, rather than creating a new one and destroying it after ever request. This is a bad thing to do for a lot of reasons.
When you say that business layer has "some cacheing", what does that mean? How are you cacheing?
I have a web application (MainApplication) where many of the pages contain a custom Web Control that looks for some content in a cache. If it can't find any data within the cache, then it goes out to a database for the content. After retrieving the content, the Control displays the content on the page.
There is a web application (CMS) in a subdirectory within the aforementioned web application. Users use this CMS to update the content pulled in by the MainApplication.
When a user updates some content using the CMS, I need the CMS to clear the relevant portion of the cache used by the MainApplication. The problem is that, as two different web applications, they can't simply interact with the same static cache object.
The ideal solution would be to somehow share an instance of a cache object between both web applications.
Failing that, what would be the best (performance-wise) way of communicating between the two web applications? Obviously, writing/reading to a database would defeat the purpose. I was thinking about a flat file?
Update
Thank you all for your help. Your wonderful answers actually gave me the right search terms to discover that this was a duplicate question (sorry!): Cache invalidation between two web applications
We had the exact same setup in a previous project i worked on, where we had one ASP.NET Web Application (with MCMS Backing), and another ASP.NET Web Application to display data.
Completely different servers (same domain though).
However, when a "editor" updated content in the CMS application, the UI was automatically refreshed.
How? Glad you asked.
We stored the content in SQL Server, and used Replication. :)
The "frontend" Web Application would read the data from the database (which was replicated by the CMS system).
Now - we don't cache this data, because in the database, we actually stored the markup (the HTML) for the control. Therefore we dynamically re-rendered the HTML.
Why is that "defeating the purpose"?
You can't get one application to "invalidate" the cache on another application.
If you're going down this path, you need to consider a distributed caching engine (e.g Velocity).
One option that comes to my mind in such scenario is using Velocity distributed cache mechanism. Do read about it and give it a try if possible http://msdn.microsoft.com/en-us/magazine/dd861287.aspx
In ASP.NET there is the notion of Cache Dependency. You can have a look here: http://www.codeproject.com/KB/web-cache/CachingDependencies.aspx or http://www.devx.com/dotnet/Article/27865/0/page/5.
There is also the Enterprise Library Caching Block available here that adds some feature to the standard stuff: http://msdn.microsoft.com/en-us/library/ff649093.aspx
Now, if you're running on .NET 4, there is a new System.Runtime.Caching namespace that you should definitely use: http://msdn.microsoft.com/en-us/library/system.runtime.caching.aspx
This article here "Caching in ASP.NET with the SqlCacheDependency Class" is quite interesting: http://msdn.microsoft.com/en-us/library/ms178604.aspx