I was in the middle of a posting on some more advanced concepts regarding the querying of CRM via the new LINQ provider (Microsoft.Xrm.Client) when I discovered another hidden gem. I’ve now proven the concept and it is so useful, I had to post about it immediately.
Cache Invalidation Plugin
After the release of the new CRM 4.0 SDK, there was a lot of talk generated about the “all or nothing” caching mechanism. Much of that talk can be found on the Codeplex CRM Accelerator site, due to the Accelerator’s heavy reliance on the xRM client and portal libraries.
There is a hint in a couple of the postings (and somewhere in the xRM documentation I believe) of a Cache Invalidation Plugin; however, no specifics are available and it was subsequently announced that it didn’t get shipped. Well, guess what? IT WAS SHIPPED!! And it’s living inside the same Microsoft.Xrm.Client.dll that we’re all using to help write our fancy new LINQ queries!!
I found it when browsing the assembly with truly magnificent .NET Reflector tool:
How It Works
In order to use the plugin, you must register it in the CRM using the Plugin Registration tool or similar. Once the assembly has been registered, you can register steps for whichever entities and messages that you wish. In my test, I chose to register steps for the Create, Update and Delete messages on the “incident” (Case) entity; mostly due to the fact that our clients have all required some form of access via the Partner Portal to Cases.
If you dig hard enough in the documentation and in postings around the web, you will find sufficient reference to the Portal framework’s Cache Invalidation Handler. It is mapped to:
http://<portalwebsite>/Cache.axd
So, the next question is, “how does the plugin know how to find the cache invalidation handler?”.
The Portal framework’s CMS entities, contain (among many others) a Web Site entity; that entity has an attribute called ‘Cache Invalidation Handler URL. Naturally, I initially thought it worked by looking at this attribute, but… it does not.
.NET Reflector to the rescue again!! When I updated case entities, there was a corresponding error in the log from the plugin telling me that the parameter “configurationXml” cannot be null. Which is basically telling us that we need to supply a configuration XML when we regsister a step for our plugin assembly. Digging into Reflector again, I found:
So… we must supply a “Secure Configuration”, but what should it look like? Back to Reflector:
So, the Configuration constructor throws the “configurationXml” null argument exception that I found in the CRM error log. It requires that the configuration xml contain a “configuration” root node and builds a name/value collection from the subnodes. Getting there…
So, we need a Configuration element with the name “invalidateCacheUrl”. OK, so the final secure configuration XML looks like:
<configuration> <invalidateCacheUrl>http//[websiteurl]/Cache.axd</invalidateCacheUrl> </configuration>
When I registered the steps, I modified the Description so that I could easily identity them in the CRM System Jobs view:
I’ve only done some preliminary testing with the Case (incident) entity, but I have no reason to believe that it won’t work with any or all of the entities; it is the same mechanism that many of us have been using, albeit rather more heavy handed. But now, we can invalidate per entity instance.
Enjoy!