Embrace the extensions mindset with Dynamics 365 for Finance and Operations #2 – SysExtension framework [EN]

In my previous post Embrace the extensions mindset with Dynamics 365 for Finance and Operations we reflected on some of the patterns we can leverage to create our customizations by using only non-intrusive changes based on a real example: Adding a new Number Sequence to a standard module.

In particular, we discussed:

  • Metadata Extensions — to add a new Enum Value in a standard Base Enum.
  • Class Extensions — to add a new method to a standard class.
  • Chain-of-Command — to add a block of code to an existing standard class method.
  • Event-Handler subscription — to subscribe our own method to an existing standard delegate provided as an extension point.

If you still didn’t read that blog post, please take a moment now. If you already did it (thanks!), let’s continue with another pattern we have to consider: SysExtension Framework (also SysPlugin, that is quite similar).

This pattern allows us to create new sub-classes for factory methods without any over-layering or coupling with the original hierarchy. Therefore, we can add new sub-classes in our own packages without any intrusive modifications and replace a very common pattern, widely used all over the application, like this (taken from AX 2012 R3):

static SalesCopying construct(SalesPurchCopy salesPurchCopy)
{
    <strong>switch(salesPurchCopy)</strong>
    {
        case SalesPurchCopy::CreditNoteHeader       : return new SalesCopying_CreditNote();
        case SalesPurchCopy::CreditNoteLines        : return SalesCopyingCreditNoteLine::construct();

        case SalesPurchCopy::CopyAllHeader          :
        case SalesPurchCopy::CopyAllLines           :
        case SalesPurchCopy::CopyJournalHeader      :
        case SalesPurchCopy::CopyJournalLines       : return new SalesCopying();

        //
        case SalesPurchCopy::VoidFiscalDocument_BR  : return new SalesCopying_VoidFiscalDocument_BR();
        //

        default                                     : <strong>throw error</strong>(strFmt("@SYS19306",funcName()));
    }

    <strong>throw error</strong>(strFmt("@SYS19306",funcName()));
}

This pattern has many of problems to be extensible. The most obvious is likely the throw error on the default case, that makes impossible to an extension class to subscribe to the Post event on the method to add new cases. But even deleting this throw sentence (that has been indeed deleted in many standard methods as a quick way to make them extensible), the pattern itself is still a problem. If a new customer or partner customization or even a new standard module needs a new case, this class needs to be modified and the full package compiled and deployed.

 

Read the full article at “Dynamics AX in the Field”, the blog from the Premier Field Engineering team at Microsoft.

 

Libro: Clean Code

Hace mucho que no comento libros. Lo más curioso es que el libro que os traigo hoy siempre fue, en mi cabeza, el primero que debí haber traído. Esa fue la idea originalmente, pero después decidí omitirlo porque, aplicado al desarrollo de puro X++ no tenia tanto sentido. Lo tenía, de hecho, pero sólo podía apreciarse después de leerse el libro, así que era un mal aliciente para fomentar su lectura.

“You are reading this book for two reasons. First, you are a programmer. Second, you want to be a better programmer. Good. We need better programmers.”

Sin embargo me he visto últimamente consultándolo a menudo (y otros que comentaré también) al pensar e investigar sobre Dynamics 365 for Finance and Operations, el nuevo modelo de Extensiones, y el esfuerzo que el equipo de producto está haciendo para hacer el sistema más “extensible“. Os lo resumo: están haciendo el código más limpio, más Clean Code, porque el código limpio es extensible por definición:

Así que me viene al pelo, por fin, hablar de este libro (está traducido como Código Limpio, aunque es más caro que el original en inglés):

La verdad es que es difícil comentar este libro porque prácticamente cualquier desarrollador en cualquier tecnología debería leerlo antes de hacer ninguna otra cosa. Si tienes unas pocas horas de formación al año, leer este libro es probablemente la mejor inversión de ese tiempo, sea cual sea el lenguaje o la plataforma para la que desarrollas, y eso incluye por supuesto Microsoft Dynamics y en particular X++ (y sobre todo en la nueva versión).

El libro trata todos los aspectos de la tarea de escribir código de manera profesional (esto es, código que debe ser mantenido, actualizado, ampliado y rentable), como el propio Martin (también conocido como Uncle Bob) escribe:

“One difference between a smart programmer and a professional programmer is that the professional understands that clarity is king. Professionals use their powers for good and write code that others can understand.

Sobre todo la primera parte cubre todos los niveles de la tarea de escribir código que sea fácil de entender (y por tanto, de mantener). Esto es muy importante porque es la base para que después funcione la técnica de extensiones (que hemos heredado de C#):

“Functions should do one thing. They should do it well. They should do it only.”

Incluye todos los aspectos del código, incluyendo los comentarios:

“Redundant comments are just places to collect lies and misinformation.”

Y también los test, acuñando términos como los Clean Tests: F.I.R.S.T (Fast, Independent, Repeatable, Self-Validating, Timely). Durante este recorrido, el texto va profundizando en la forma de pensar que después nos llevara a conceptos más complejos como los patrones de diseño, o los principios del diseño orientado a objetos como S.O.L.I.D.

Si has leído la documentación sobre Extensiones en Dynamics 365 for Finance and Operations, te sonarán al menos dos de esos principios: la O (Open-Clossed Principle) y la L (Liskov Substitution Principle). Tanto si te suenan como si no, pásate por el Dynamics Saturday de Madrid el 19 de Mayo porque hablaremos de ellos y de más cosas interesantes 🙂

También profundizaré sobre estos principios y patrones en los próximos artículos de este blog y el de mi departamento en Microsoft: Dynamics AX in the Field.

Stay tuned!

Embrace the extensions mindset with Dynamics 365 for Finance and Operations [EN]

A couple of weeks ago, we launched the last platform update 10 (August 2017) for Dynamics 365 for Finance and Operations, Enterprise Edition and, as in almost every release, there were changes regarding the Application Extensibility Plans.

A lot of effort is being invested in the journey to a non-intrusive way to extend the application, and it needs to be understood as a critical change in the way we think about customizations. More information about future plans can be found in the Dynamics Roadmap (Filter – Application: Dynamics 365 for Finance and Operations; Area: Extensibility).

But sometimes it’s hard to change our mindset just by looking at these out-of-context upgrade notes, so I want to show how we can leverage some of the latest improvements to the X++ platform by looking at some real-life examples.

Keep in mind the basic principle: we want to avoid intrusive changes.

 

Scenario 1: Create a number sequence in a standard module

This is a common scenario and the good news is that it has barely changed from Dynamics AX 2012. In our example, we will add a new number sequence to the Accounts Receivables module (Customers) to provide new values for the custom MSVRMInsuranceProviderId EDT. To accomplish that, we need to make some small changes (plenty of examples of AX 2012 code available out there):

 

Read the full article at “Dynamics AX in the Field”, the blog from the Premier Field Engineering team at Microsoft.

 

Trabajando con la máquina virtual de desarrollo local en Dynamics 365 for Operations

No voy a escribir una entrada sobre cómo configurar una MV local de Dynamics 365 for Operations para desarrollo, porque ya se han publicado muchísimas desde el lanzamiento del producto hace unos meses. También está publicado en la documentación oficial de forma bastante clara, así que sería repetir lo que ya se ha explicado mil veces.

Lo más importante es configurar bien la conexión con el proyecto de Visual Studio Team Services y con la rama que estemos utilizando, mapeando de forma acorde las carpetas locales. Por ejemplo:

  • La carpeta Metadata debe apuntar a donde están almacenados los paquetes de Dynamics 365 en el disco. Dependiendo de la versión de la máquina virtual pueden estar en C:\AOSService\PackagesLocalDirectory o en C:\Packages (en las versiones antiguas).
  • La carpeta Projects normalmente se configura en la carpeta por defecto donde Visual Studio almacena los proyectos (en Mis Documentos), pero esto dependerá de la estructura que siga cada equipo para almacenar los proyectos que, recordemos, no forman parte de los metadatos de AX en esta versión, como sí hacían los proyectos del AOT de versiones anteriores.

También hay una serie de propiedades que se pueden modificar para que la máquina se comporte de una forma más natural para un desarrollador de AX e incluso para mejorar un poco el rendimiento.

Siguiendo con nuestra cadena respecto a la introducción al desarrollo para Dynamics 365 for Operations, voy a comentar algunos escenarios que suceden mucho y parecen ser problemáticos para programadores que empiezan a utilizar las nuevas herramientas. Pequeños detalles que conviene no olvidar. Es posible que actualice este post en el futuro para tenerlos todos localizados:

Continue Reading…

Internet of Fun – Demostrando el concepto IoT

big-bang-t3e23-jaestevan

En un artículo anterior, hacía una introducción del concepto de Internet of Things (IoT, Internet de las Cosas) y por qué iba a ser relevante en el futuro en multitud de procesos empresariales, procesos que inevitablemente van a llegar al mundo del ERP en mayor o menor medida.

Uno de los factores que, en mi opinión, van a hacer que estas prácticas se disparen en un futuro cercano es su accesibilidad. La facilidad de desarrollarlos y el bajo coste con el que se puede empezar a hacer cosas útiles y de eso estamos hablando, ¿Verdad?… de cosas 🙂

En la demostración que empieza con este post vamos a crear un ejemplo funcional sencillo para comprobar las posibilidades de las que disponemos en cada caso, y comprobar lo sencillo que puede ser investigar y crear prototipos que luego podremos convertir en sistemas reales. Utilizaremos materiales de bajo coste para hacer pruebas, que luego podremos convertir en sistemas reales con material industrial equivalente.

Este artículo contará por lo menos con tres partes (puede que más, si el tema interesa) teniendo en cuenta los que para mi son los tres boques de estas técnicas: Sistemas que van a generar la información (las “cosas” del IoT), los consumidores que harán uso de esta información, y los canales que nos permitirán capturar, almacenar y procesar la información generada.

grafico-iot-jaestevan

Continue Reading…

Control de versiones en Microsoft Dynamics AX 2012 mediante ramas de Team Foundation Server (ALM-VII)

En capítulos anteriores hablamos sobre cómo instalar y configurar Team Foundation Server, así como las posibilidades que ofrece para gestionar tareas y administrar el código fuente desde nuestra instancia de Microsoft Dynamics AX 2012. Comentamos las funciones básicas ,aunque imprescindibles, para proteger y desproteger el código en el servidor y las ventajas que ello suponía en cuanto a almacenar todo el histórico de cambios de los objetos, como por ejemplo: revisar el historial de cambios de un objeto, volver a una versión anterior, descartar cambios sin confirmar, etc.

Sin embargo hay ciertos problemas que una gestión básica del código fuente no es capaz de solucionar. Por ejemplo, en una instalación normal de nuestro ERP, a la vez que damos el soporte diario y realizamos pequeñas modificaciones para solucionar problemas, estamos llevando a cabo desarrollos de mayor o menor impacto. Estos desarrollos paralelos necesitan ser integrados en el código de producción de alguna forma, pero si usamos el mismo servidor para desarrollar y para hacer el mantenimiento, tendremos que llegar a un punto en el que todos los desarrollos estén totalmente terminados para pasar a producción de forma limpia y segura.

De la misma forma, si nuestra empresa desarrolla un producto final, es necesario avanzar el desarrollo de las siguientes versiones mientras damos soporte a las versiones publicadas en el pasado, incluso para diferentes versiones de AX. ¿Cómo estar seguro que un hotfix urgente desarrollado para un cliente llega a todas las versiones de nuestro producto que la necesitan, de forma limpia y estable?

Visual Studio loves Dynamics AX 2012

Por supuesto hace falta un buen método de trabajo para que todo esto pueda realizarse de forma ordenada y sin errores, pero también hace falta la ayuda de alguna herramienta y para eso tenemos las ramas (Branches) disponibles en casi todos los sistemas de control de versiones del mercado, y por supuesto en nuestro Team Foundation Server.

Estrategias de branching

Existen infinidad de estrategias para definir las ramas que necesitamos en nuestros equipos, y ello va a depender de la cantidad de equipos que tengamos, la cantidad de productos, de versiones, etc. NO HAY una estrategia de ramas estándar o válida para todos y es algo que se debe pensar con cuidado ya que la estrategia elegida nos va a suponer ventajas e inconvenientes. Lo más recomendable es empezar por la lectura de la guía Version Control Guide escrita por el grupo Visual Studio ALM Rangers donde explican la mayoría de opciones con sus pros y sus contras.

Continue Reading…