WCF Contrib v2.1 – Client Channel Output Caching
Via http://wcfcontrib.codeplex.com/wikipage?title=ClientChannelOutputCache.
A new feature that arrived at WcfContrib v2.1 Feb10 Beta.
You can use the output caching to cache the operation output with the setting of your desire.
This is extremely useful and may save you quite some time from building client caching stores.
The built-in mechanism implemented here is In-Proc in-memory cache using the synchronized dictionary that comes with WcfContrib as well.
You can fully customize it and change the underlying provider or store. (E.g. EntLib/ASP.NET Caching/AppFabric caching/Database/File system and whatnot)
If the result is present in the cache and is still active according to its policy and interval, this result is returned without going through the WCF pipeline whatsoever which enables very good performance.
Usage Guideline
If you're using the output caching feature, you should dispose the controller instance at your process exit point:
using (OutputCacheController.Current) { }
Features
- Output Cache on several elements - The behavior can be attached to a client channel for either a specific client channel instance or contract or specific operations.
- Different cache policies - Absolute / Sliding / Indefinite.
- Ignore Default Value - There may be services which return null when a certain entity isn't found for example, in this case you can use this mode to avoid caching it so next time it will still call the service to try and fetch the entity. (defaults to false)
- Compare Enumerable Items - When set to true (the default), A custom equality comparer will be used with IEnumerable parameters since in this case you usually don't want to check equality by reference.
- Equality Comparers - You can provide your own set of equality comparers to be used, this is index-based.
- Provider Factory Model - The model is fully customizable
What is NOT supported
The behavior doesn't support operations with out/ref parameter definitions.
This is due to the fact that the 'IClientOperationInvokerBehavior' (the core implementation for this behavior) wasn't designed while taking this into account in the first place.
This will be addressed in a future release.
Usage Scenarios
Contract-level Definition [ServiceContract]
//This will affect only 'Do' in this case
//since the other operations have the behavior set explicitly on them
[OutputCacheBehavior(OutputCachePolicy.Absolute, 3000)]
interface IService
{
[OperationContract]
void Do(Foo foo);
[OperationContract]
[OutputCacheBehavior(OutputCachePolicy.Sliding, 2000)]
Foo GetFoo1();
//Both the synchronous and asynchronous need to be tagged with the behavior,
//It will use the same underlying source for both of them, no worries.
[OperationContract(AsyncPattern = true)]
[OutputCacheBehavior(OutputCachePolicy.Sliding, 2000)]
IAsyncResult BeginGetFoo1(AsyncCallback callback, object asyncState);
Foo EndGetFoo1(IAsyncResult result);
}
Client-channel based definition:
ClientChannel<IService> myChannel = new ClientChannel<IService>(...);
//Add output cache to a specific operation
//You can add it to the entire description or contract behaviors which will affect
//all operations that were not set with the behavior explicitly on them
//You can also change the description of the global instance (ClientChannel<IService>.Instance)
myChannel.Description.Contract.Operations[0].Behaviors.Add(new OutputCacheBehaviorAttribute(...));
Derived ClientChannel definition:
You can attach the behaviors in the InitializeRuntime or through attributes on your own derived client channel.
For more information see ClientChannel documentation file on the Client Channel Extensions model.
Customizing the output cache provider
I will explain about it in a future post