martes, 20 de enero de 2015

Scripting GX C# con Jint 2.4


Amigos, en esta ocasión hago un "update" del tema de scripting con Jint, uno de los engines javascript que podemos usar con C#, que desde un tiempo pasó a la versión 2.0 con importantes mejoras.

En esta pasada aprovecho de mostrarles cómo hacer para que desde el javascript puedan llamar a procedures gx que estén en la misma KB, lo que favorece de buena forma las posibilidades de este tipo de integración y su aplicación en casos reales.

Pondremos en un procedure jintEngine el código de más abajo, en el que se puede apreciar en las primeras líneas el truco para "cortar" el C# generado por GX y meter en medio una definición de "delegate" y un método que usaremos luego para llamar a un procedure gx desde el javascript. Nótese que el método recibe un string y retorna otro string, tal como el "delegate".

 parm(&jsVarchar,&returnVarchar,&isOK);
 csharp     executePrivate2();
 csharp }
 csharp public delegate string getObjectDeleg(string inStr);
 csharp private string getObject(string inStr)
 csharp {
         csharp [!&in!] = inStr;
         //acá la lamada a otro procedure de nuestra kb
         jintGetObjJsonString.call(&in,&ret)
         csharp return [!&ret!];
 csharp }
 csharp void executePrivate2( )
 csharp {
 
 // código para instanciar el engine Jint
 &returnVarchar = ""
 &isOK = true
 csharp try {
         csharp var engine = new Jint.Engine(cfg => cfg.AllowClr());
         //acá hacemos una instancia del delegate
         csharp getObjectDeleg getObjectDelegInstance = new getObjectDeleg(getObject);
         //y se lo pasamos al engine
         csharp engine.SetValue("getObjJsonStr",getObjectDelegInstance);
         //ejecutar el javascript que viene en &jsVarchar
         csharp engine.Execute([!&jsVarchar!]);
          //el resultado lo dejamos en &returnVarchar
         csharp [!&returnVarchar!] = engine.GetCompletionValue().ToString();
 csharp }
 csharp catch ( Exception e ){
         csharp [!&returnVarchar!] = e.ToString();
         &isOK = false
 csharp }  
El procedure jintGetObjJsonString podrá ser invocado desde el javascript con getObjJsonStr, de acuerdo a cómo se lo pasamos al engine con SetValue.
Para este procedure podríamos tener el siguiente código:
 parm(&in,&ret); //parms de tipo varchar
 //asumimos que en &in viene un json con la estructura de &sdtEntrada
 &sdtEntrada.fromjson(&in)
 ...
 // aquí lo que sea que se necesite para cargar el &sdtSalida
 ...
 &ret = &sdtSalida.tojson() 

Un ejemplo de javascript que podríamos ejecutar:
 //objeto a usar como parm (con la misma estructura de &sdtEntrada)
 var objSdtEntrada = {Id:1,............};
 //llamada al proc gx usando delegate
 var objDesdeGX = getObjJsonStr(JSON.stringify(objSdtEntrada));
 function mainFunction(){
     ...
     var otroDesdeGX = getObjJsonStr(JSON.stringify(objSdtEntrada));
     ...
     //el retorno puede ser un json o cualquier cosa string
     return JSON.stringify(otroDesdeGX);
 }
 //finalizar con la invocación a la función "main"
 mainFunction();
Lo importante de este ejemplo es mostrar cómo se invoca el método delegate mediante la función getObjJsonStr, que finalmente llama al procedure jintGetObjJsonString, y que debemos usar una función para hacer el return que Jint atrapa con GetCompletionValue.

Un abrazo y buen 2015 a todos.
salu2!

P.D.: para este año me gustaría que Artech nos anunciara un generador web basado en AngularJS.