2 min read

X++ Chronicles : How to cache a variable using SysGlobalCache

X++ Chronicles : How to cache a variable using SysGlobalCache
Photo by Mohammad Rahmani / Unsplash

In case “SysGlobalCache” doesn’t ring any bells, I suggest taking a look here to begin with : https://docs.microsoft.com/en-us/dynamicsax-2012/developer/how-to-use-the-sysglobalobjectcache-class-for-better-performance

For the sake of the exercise, let’s say you need to drag along with you in the entire session a variable. This can be achieved very easy when you are passing args, as long as you have this option. You just attach the variable to the args and you are done. But let’s assume you don’t have that option, because, and I’m sure this is no new stuff for you, there are a lot of developments in Dynamics 365 Finance which rely entirely upon EventHandlers. So how do we pass variables in the user session through the entire flow, from Classes to EventHadlers and so on?

We will mention just 2 although we can think of a few more :

  1. You can store the variable at the DB level, and just query it, update or delete as you might see fit, but I wouldn’t recommend this approach when you are running high intensive process computations. Another limitation here is that if you want to have specific variable values based on the user interaction in the system you will have as many rows as users per variable. If you need more variables, in time, it can become a nightmare to manage it.
  2. You can store the variable in the SysGlobalCache of the Dynamics 365 Finance and just use it when you need. In this scenario you don’t have the user limitation because SysGlobalCache is smart enough to know for which user you have stored this information and fed it back when you required it. Let me show you how we achieved this in a few steps.
  • First of all, you need to declare the variables in the EventHandler in which you will interact with SysGlobalCache
[FormDataFieldEventHandler(formDataFieldStr(SalesTable, SalesLine, ItemId), FormDataFieldEventType::Validating)]
public static void ProductId_OnValidating(FormDataObject sender, FormDataFieldEventArgs e)
{
   SysGlobalCache globalCache;
   globalCache = ClassFactory.globalCache();
   //......
}
  • Then you will have to get the Current Process Id of the application
var curPId = System.Diagnostics.Process::GetCurrentProcess().Id;
  • After this, you will have to set a value in the SysGlobalCache, based on the value of the variable, the Current User Id and the Current Process Id ( 0 is the position of the variable in the array, in case you need multiple variables ) using globalCache.set
globalCache.set(strFmt("%1%2%3%4", curUserId(), classStr(Product_EventHandlers), currentProcessId), 0, theVariableYouNeedToDragAlong);
  • Once you have the value stored in the SysGlobalCache you can you use in a lot of places , let’s say another EventHandler stored in the same class, using globalCache.get
[FormDataFieldEventHandler(formDataFieldStr(SalesTable, SalesLine, ItemId), FormDataFieldEventType::Validating)]
public static void SaleLineId_OnValidating(FormDataObject sender, FormDataFieldEventArgs e)
{
   SysGlobalCache globalCache;
   globalCache = ClassFactory.globalCache();
   var curPId = System.Diagnostics.Process::GetCurrentProcess().Id;
   str theVariableYouNeedToDragAlong = globalCache.get(strFmt("%1%2%3", curUserId(), classStr(Product_EventHandlers), curPId), 0);
   // now you can use theVariableYouNeedToDragAlong here 
}
  • After you are done using the variable, the final step is to remove it from the cache, based, again, on the position of the variable
 globalcache.remove(strFmt("%1%2%3", curUserId(), classStr(Product_EventHandlers), curPId), 0);

Thanks for reading this article, hope it was helpful 😊. If you have any questions please leave a comment below.