Business Central 2020 Wave 1: Intefaces y Enums - Business Central

Breaking

domingo, 8 de marzo de 2020

Business Central 2020 Wave 1: Intefaces y Enums

Nivel: developer

Como usar Interfaces y Enums


Con la llegada de la nueva versión de Business Central (2020 Wave 1) tenemos un nuevo elemento de programación que nos indica que nuestro Navision se encamina cada vez más a la programación orientada a objetos.  Son las interfaces.  

Pese a que todavía no hay mucha documentación oficial, he preparado un ejemplo práctico que nos permitirá ver su uso: crear y usar una codeunit, permitiendo la implementación posterior (o en nuevas apps) del contenido de cada uno de sus procedimientos.  Es decir, la abstracción.


Instalación de Business Central 2020 Wave 1 (BC 16).

Si quieres probar la nueva versión, puedes crearte un Sandbox con la Preview de BC16:




Con esta opción, ya podríamos probarlo funcionalmente pero para programar algo, necesitaremos descargarnos el fichero VSIX del DVD de la nueva versión Preview de Business Central 2020 Wave 1, ya que el VSCode todavía no tiene la actualización de la extensión de AL Language:




Definir una interface.

Una vez instalado el entorno, podemos empezar a desarrollar nuestra aplicación.  En mi caso, consistirá en una importación de ficheros de texto, que me permitirá inicialmente, crear Clientes o Productos.  Es cierto que podríamos usar las sentencias IF o CASE y funcionaría igual, pero como veremos, hacer una extensión de mi aplicación será más sencillo usando las Interfaces.

Para definirla usaremos la siguiente estructura:





Por un lado el nombre de la interface (en mi caso ImportFiles).  En su interior, cada uno de los procedimientos que queramos usar, pero sin definir su contenido.

De esta forma, se puede separar la programación por desarrolladores.  Uno realizaría el contenido de cada procedimiento sin importarle como se use.  El otro, llamaría al procedimiento sin importarle su implementación.

Implementar los procedimientos.

Para implementar los procedimientos, creamos codeunits como habitualmente, con el nombre que queramos y añadiendo la terminación Implements y el nombre de la interface que implementa (en mi caso ImportFiles).  En su interior, creamos cada uno de los procedimientos definidos en la interface (en mi caso ImportFile)


Lo que hace el procedimiento es leer un fichero de texto mediante la instrucción UploadIntoStream y rellenar una tabla especial llamada "CSV Buffer", que como su nombre indica, nos permite leer ficheros CSV (para los que añoran los dataport). Una vez leido el fichero, crea o modificar clientes.

La estructura del fichero es la siguiente:


Haremos una nueva implementación de nuestra interface, para poder importar en este caso, productos.  Como vemos es otra codeunit, pero con el mismo nombre de procedimiento ImportFile


Ahora vamos a ver como llamar a las diferentes opciones de implementación.

Usando Enum en lugar de Option

Una de las novedades que tuvimos con la llegada del AL frente al C/AL fue el tipo de datos Enum, que son como los Option, pero con la posibilidad de poder ser ampliados (extendidos).




Ahora, junto con las interfaces, hacen una pareja muy interesante.  Al definir el Enum, podemos decirle que está relacionado con una interface, añadiendo "implements NOMBRE_INTERFACE":





En el ejemplo, el Enum permite seleccionar entre los valores Customers o Items, para determinar que tipo de fichero vamos a importar, pero además le hemos indicado que está relacionada con la interface "ImportFiles", y en cada valor del Enum, nos permitiría seleccionar con la propiedad "Implementation" cual de las diferentes implementaciones debe usar: codeunit ImportCustomers o importItem.


Llamando a las interfaces

Ya solamente nos quedaría llamar a las diferentes implementaciones de las interface creada.  Para ello diseñamos una página, donde crearemos una variable de tipo Enum y subtipo "TypeOfFile" que previamente habíamos definido (línea 41) a la que llamaremos TypeList.




Vincularemos dicha variable a un campo en nuestra página (Línea 14).

Crearemos una Action para realizar la importación del fichero (Línea 26).  Pero, ¿qué fichero? el que determine el Enum, o más bien, la implementación indicada en su definición.  Para ello:

  • Dentro de la Action definimos una variable id de tipo Interface y subtipo ImportFiles (línea 32)
  • Asignamos a dicha variable, el valor del Enum TypeList (Línea 34)
  • Llamamos al procedimiento id.ImportFile de la implementación de la interface seleccionada, mostrando true o false en función del resultado de la importación (Línea 35)

Probamos la extensión

Efectivamente, al seleccionar cada opción en el Enum y pulsar la acción "Import File", nos abre la implementación correspondiente (importCustomers o importItem):


Implementación de la interface ImportCustomers
Implementación de la interface ImportItem


Si quieres probar el código, está disponible en https://github.com/RCORELLA/Interfaces

Conclusiones

Como he comentado antes, esto mismo se podría haber realizado también con un IF o con un CASE, pero ¿Y si alguien quisiera extender mi extensión importando un fichero de Recursos?  Sería mucho más fácil y menos intrusivo realizarlo con Interfaces y Enums.

Lo probaremos en la próxima entrada.

Agradecimientos.

Tal y como he comentado, todavía no hay mucha documentación oficial sobre interfaces, por lo que tengo que agradecer a Tobias Fenster y Stefano Demiliani por las aportaciones en sus blogs.







No hay comentarios: