After asp. net4.0, we can implement our own OutputCacheProvider to control the cache location. However, I find that many OutputCacheProvider calls are not very clear. First, we need to know where the cache is registered. The answer is OutputCacheModule.
Void IHttpModule. Init (HttpApplication app)
{
If (RuntimeConfig. GetAppConfig (). OutputCache. EnableOutputCache)
{
App. ResolveRequestCache + = new EventHandler (this. OnEnter );
App. UpdateRequestCache + = new EventHandler (this. OnLeave );
}
}
(RuntimeConfig. GetAppConfig (). OutputCache. EnableOutputCache: Check our configuration to see if you have enabled the cache. OnEnter reads the cached data before processing and sets the cache after processing.
So let's take a look at the OnEnter method. I will delete most of the code and only keep the main results.
Internal void OnEnter (object source, EventArgs eventArgs)
{
This. _ key = null;
String str;
This. _ key = str = this. CreateOutputCachedItemKey (context, null );
Object obj2 = OutputCache. Get (str );
If (obj2! = Null)
{
CachedVary cachedVary = obj2 as CachedVary;
If (cachedVary! = Null)
{
Str = this. CreateOutputCachedItemKey (context, cachedVary );
Obj2 = OutputCache. Get (str );}
Application. CompleteRequest ();
Return;
}
Return;
}
}
There are two calls: obj2 = OutputCache. get (str), let's analyze it. The data obtained for the first time is converted to cachedVary, which is an instance that stores the attribute configurations in our OutputCache, therefore, different attributes of OutputCache produce different cachedVary values, while the obj2 read for the second time is what we really need to save, after it is obtained, a series of processing operations are performed to end the http request.
If the value is set twice, the setting must be set twice.
Internal void OnLeave (object source, EventArgs eventArgs)
{
CachedVary vary;
String str;
Vary = new CachedVary (varyByContentEncodings, varyByHeaders, varyByParams, varyByAllParams, currentSettings. VaryByCustom );
Str = this. CreateOutputCachedItemKey (context, vary );
HttpRawResponse snapshot = response. GetSnapshot ();
String kernelCacheUrl = response. SetupKernelCaching (null );
Guid cachedVaryId = (vary! = Null )? Vary. CachedVaryId: Guid. Empty;
CachedRawResponse rawResponse = new CachedRawResponse (snapshot, currentSettings, kernelCacheUrl, cachedVaryId );
CacheDependency dependencies = response. CreateCacheDependencyForResponse ();
OutputCache. InsertResponse (this. _ key, vary, str, rawResponse, dependencies, noAbsoluteExpiration, noSlidingExpiration );
}
}
Here we see two instances of CachedVary and CachedRawResponse. Here we can determine that the obj2 that previously called obj2 = OutputCache. Get (str) for the second time should be a CachedRawResponse instance. The InsertResponse method of OutputCache:
Internal static void InsertResponse (string cachedVaryKey, CachedVary cachedVary, string rawResponseKey, CachedRawResponse rawResponse, CacheDependency dependencies, DateTime absExp, TimeSpan slidingExp)
{
OutputCacheProvider provider = GetProvider (HttpContext. Current );
Provider. Set (cachedVaryKey, cachedVary, Cache. NoAbsoluteExpiration );
Provider. Set (rawResponseKey, entry, absExp );
}
As you can see, I understand that both the storage and read operations of OutputCache are two instances. One is the configuration instance CachedVary of OutputCache, and the other is the real data stream CachedRawResponse.
We can see that the InsertResponse method of OutputCache mentions OutputCacheProvider provider = GetProvider (HttpContext. Current) and calls this sentence in the Get method of OutputCacheProvider.
[Csharp]
Internal static object Get (string key)
{
Object obj2 = null;
OutputCacheProvider provider = GetProvider (HttpContext. Current );
If (provider! = Null)
{
Obj2 = provider. Get (key );
OutputCacheEntry oce = obj2 as OutputCacheEntry;
If (oce! = Null)
{
If (HasDependencyChanged (false, oce. DependenciesKey, oce. Dependencies, oce. KernelCacheUrl, key, provider. Name ))
{
RemoveFromProvider (key, provider. Name );
Return null;
}
Obj2 = Convert (oce );
}
}
If (obj2 = null)
{
Obj2 = HttpRuntime. CacheInternal. Get (key );
}
Return obj2;
}
Internal static object Get (string key)
{
Object obj2 = null;
OutputCacheProvider provider = GetProvider (HttpContext. Current );
If (provider! = Null)
{
Obj2 = provider. Get (key );
OutputCacheEntry oce = obj2 as OutputCacheEntry;
If (oce! = Null)
{
If (HasDependencyChanged (false, oce. DependenciesKey, oce. Dependencies, oce. KernelCacheUrl, key, provider. Name ))
{
RemoveFromProvider (key, provider. Name );
Return null;
}
Obj2 = Convert (oce );
}
}
If (obj2 = null)
{
Obj2 = HttpRuntime. CacheInternal. Get (key );
}
Return obj2;
}
I won't mention what the GetProvider method of OutputCache does. I believe everyone will understand it.
To implement custom cache, You can implement your own OutputCacheProvider and register your OutputCacheModule.
[Csharp]
Public class MemoryCacheProvider: OutputCacheProvider
{
Public override object Add (string key, object entry, DateTime utcExpiry)
{
Return null;
}
Public override object Get (string key)
{
Return null;
}
Public override void Set (string key, object entry, DateTime utcExpiry)
{
}
Public override void Remove (string key)
{
}
}
Ic class CustOutputCacheModule: IHttpModule
{
Public void Dispose ()
{
}
Public void Init (HttpApplication context)
{
Context. ResolveRequestCache + = new EventHandler (context_ResolveRequestCache );
Context. UpdateRequestCache + = new EventHandler (context_UpdateRequestCache );
}
Void context_UpdateRequestCache (object sender, EventArgs e)
{
}
Void context_ResolveRequestCache (object sender, EventArgs e)
{
}
}
Public class MemoryCacheProvider: OutputCacheProvider
{
Public override object Add (string key, object entry, DateTime utcExpiry)
{
Return null;
}
Public override object Get (string key)
{
Return null;
}
Public override void Set (string key, object entry, DateTime utcExpiry)
{
}
Public override void Remove (string key)
{
}
}
Public class CustOutputCacheModule: IHttpModule
{
Public void Dispose ()
{
}
Public void Init (HttpApplication context)
{
Context. ResolveRequestCache + = new EventHandler (context_ResolveRequestCache );
Context. UpdateRequestCache + = new EventHandler (context_UpdateRequestCache );
}
Void context_UpdateRequestCache (object sender, EventArgs e)
{
}
Void context_ResolveRequestCache (object sender, EventArgs e)
{
}
}
The corresponding configuration is
<Caching>
<OutputCache defaultProvider = "ChannelInMemory">
<Providers>
<Add name = "ChannelInMemory" type = "MvcApp. MemoryCacheProvider, MvcApp"/>
</Providers>
</OutputCache>
</Caching>
<HttpModules>
<Remove name = "OutputCache"/>
<Add name = "OutputCache" type = "MvcApp. CustOutputCacheModule"/>
</HttpModules>
Share: