class VKSingletonTest { private int rand; public static VKSingletonTest instance() { const str mySysGlobalCacheKey = 'VKSingletonTest'; VKSingletonTest singleton; // AX2012 //SysGlobalCache globalCache = infolog.objectOnServer() ? appl.globalCache() : infolog.globalCache(); // AX7/d365 SysGlobalCache globalCache = appl.globalCache(); if (globalCache.isSet(classStr(VKSingletonTest), mySysGlobalCacheKey)) { Info('cached instance'); singleton = globalCache.get(classStr(VKSingletonTest), mySysGlobalCacheKey); } else { Info('new instance'); singleton = new VKSingletonTest(); // Additional line for AX2012 //globalCache.set(classStr(SingletonClass), mySysGlobalCacheKey, singleton); globalCache.set(classStr(VKSingletonTest), mySysGlobalCacheKey, singleton); } return singleton; } protected void new() { Random Random = new Random(); rand = Random.nextInt(); } public int getRand() { return rand; } }Simplified for D365F&SCM:
class VKSingletonTest { private static VKSingletonTest singleton = new VKSingletonTest(); private int rand; public static VKSingletonTest instance() { return singleton; } protected void new() { Random Random = new Random(); rand = Random.nextInt(); } public int getRand() { return rand; } }
class VKTest { public static void main(Args _args) { VKSingletonTest singleton = VKSingletonTest::instance(); info(strFmt("%1", singleton.getRand())); singleton = VKSingletonTest::instance(); info(strFmt("%1", singleton.getRand())); } }Both numbers will be the same in a single execution. However, for the next job execution numbers will be different.
class VKSingletonTest { private int rand; #define.CurrentVersion(1) #localMacro.CurrentList rand #endmacro public static VKSingletonTest instance() { const str myScopeKey = 'VKSingletonTest'; container cacheKey = ['VKSingletonTest']; container cacheValue; VKSingletonTest singleton; SysGlobalObjectCache globalCache = new SysGlobalObjectCache(); cacheValue = globalCache.find(myScopeKey, cacheKey); if (cacheValue == conNull()) { Info('new instance'); singleton = new VKSingletonTest(); globalCache.insert(myScopeKey, cacheKey, singleton.pack()); } else { Info('cached instance'); singleton = new VKSingletonTest(); singleton.unpack(cacheValue); } return singleton; } protected void new() { Random Random = new Random(); rand = Random.nextInt(); } public int getRand() { return rand; } public container pack() { return [#CurrentVersion, #CurrentList]; } public boolean unpack(container packedClass) { Version version = RunBase::getVersion(packedClass); switch (version) { case #CurrentVersion: [version, #CurrentList] = packedClass; break; default: return false; } return true; } }Standard example with caching values in CustVendExternalItemDescription class.
All entries in SysGlobalObjectCache can be removed for by running a class that uses the following URL:
/?mi=SysClassRunner&cls=SysFlushAOD.
The SysFlushAOD class clears all cache in SysGlobalObjectCache.
System administration / Setup / Refresh elements
If you found value in what I share, I've set up a Buy Me a Coffee page as a way to show your support.
Buy Me a CoffeeWhy do you not use this piece of code? This is a code from MS Wiki: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-ref/xpp-classes-methods
public class Singleton
{
private static Singleton instance;
private void new()
{
}
//static constructor
static void TypeNew()
{
instance = new Singleton();
}
SysGlobalCache keep values inside one AOS server.
SysGlobalObjectCache keep values across all AOS servers.
To implement a real singleton, you should use SysGlobalObjectCache not SysGlobalCache.
Completely Incorrect (regarding SysGlobalCache as well) . RTFM
A SysGlobalObjectCache object that is running in the AOS uses the same cache that is shared by all client sessions that are connected to that AOS. has access to a global cache that is shared by all client sessions.
Every record that is inserted into SysGlobalObjectCache is shared across multiple sessions that are in the same process. If an entry is inserted on the AOS, then all the sessions on the same AOS have access to the entry in the cache. However, any cache entries inserted on the AOS will not be automatically sent to the clients connected to that AOS. The entries will also not be sent to another AOS that is part of the deployment.
https://learn.microsoft.com/en-us/previous-versions/dynamicsax-2012/developer/how-to-use-the-sysglobalobjectcache-class-for-better-performance
DaxOnline.org is free platform that allows you to quickly store and reuse snippets, notes, articles related to Dynamics AX.
Authors are allowed to set their own "buy me a coffee" link.
Join us.