Maintenir les engines de Mercator dans des variables de session .net

0000002244     -      19/09/2018

En tant que tels, les différents moteurs de Mercator ne sont pas sérialisables et ne peuvent dès lors pas être sauvegardés directement dans des variables de session ASP.net. (Ceci se justifie par la complexité de la structure de ces classes ainsi que le mécanisme d'instanciation par désérialisation qui serait inadapté)

Quand Mercator est instancié pour une utilisation à partir d'une application externe, comme c'est le cas lorsque Mercator est lié à un site ASP.net, la classe statique MercatorUi.Globals contient un dictionnaire permettant de retrouver tous les engines ouverts (en cours d'utilisation) : EnginesUsedByExtApp défini comme suit : System.Collections.Concurrent.ConcurrentDictionary<string, MercatorUi.Interfaces.IEngine> (ConcurrentDictionary est thread-safe, ce qui est nécessaire pour une application ASP.net qui est multi-thread)

Cela concerne ces différents moteurs :

  • MercatorUi.Engine.Cpta.BookingEngine
  • MercatorUi.Engine.Crm.ActionEngine
  • MercatorUi.Engine.Gescom.BillingEngine
  • MercatorUi.Engine.Gescom.TransferEngine
  • MercatorUi.Engine.Gescom.InventoryEngine

Lorsqu'un de ces moteurs est initialisé à partir d'une application externe,

  • ce moteur voit sa propriété UniqueIdForExtApp complétée avec une chaîne unique
  • ce moteur est ajouté dans le dictionnaire MercatorUi.Globals.EnginesUsedByExtApp avec cette chaîne unique en tant que clé

Dès lors, il suffit de sauvegarder cette clé unique dans une variable de session. Le dictionnaire sera ensuite utilisé pour retrouver l'engine sur base de cette clé.

Exemple :

1. Lors de l'initialisation du billingEngine (caddie) pour une internaute (session) :

Zoom
MercatorUi.Engine.Gescom.BillingEngine billingEngine = MercatorUi.Engine.Gescom.BillingEngine.InitNew(MercatorUi.Engine.Gescom.Billing.TypeVAEnum.V, 3, "Comm");
if (billingEngine.DataSet != null)
{
    Session["CurrentEngineKey"] = billingEngine.UniqueIdForExtApp;
}

Attention : ici il ne faut pas utiliser la notation avec using, ce qui appelerait la méthode Dispose de ce BillingEngine et le retirerait de EnginesUsedByExtApp.

2. Sur une autre page, pour reprendre ce billingEngine et pouvoir l'utiliser :

Zoom
MercatorUi.Interfaces.IEngine engine;
if ((Session["CurrentEngineKey"] != null) && MercatorUi.Globals.EnginesUsedByExtApp.TryGetValue(Session["CurrentEngineKey"].ToString(), out engine))
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)engine;
    ...
}

3. Lorsque l'utilisateur se déconnecte du site,  lorsque le billingEngine n'est plus nécessaire ou après l'appel de la méthode Save :

Zoom
MercatorUi.Interfaces.IEngine engine;
if ((Session["CurrentEngineKey"] != null) && MercatorUi.Globals.EnginesUsedByExtApp.TryGetValue(Session["CurrentEngineKey"].ToString(), out engine))
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)engine;
    billingEngine.Dispose();
    Session.Remove("CurrentEngineKey");
}

L'appel de la méthode Dispose est absolument nécessaire pour fermer le BillingEngine (Close) et le retirer de EnginesUsedByExtApp. Si cet appel n'est pas effectué correctement, votre application ASP.net risque de rencontrer des problèmes de mémoire.

Remarques :

Etant donné que l'information sauvegardée est de taille très réduite (un simple chaîne de caractères), elle peut être stockée dans le ViewState plutôt que dans les variables de sessions. Cela permet de gérer facilement le cas où un internaute ouvre plusieurs onglets dans son explorateur Internet mais que cela correspond à des comptes clients, et donc des BillingEngines, distincts.

Zoom
Session["CurrentEngineKey"]

devient

Zoom
ViewState["CurrentEngineKey"]

 

Les ressources évoquées ici ne sont disponibles que dans la version de MercatorUi.dll compilée compilée pour le Framework .net 4.0. (Les ConcurrentDictionaries n'existent pas dans les versions antérieures)