An Introduction to OutputCacheProvider OutputCache

Source: Internet
Author: User

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:

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.