Algunas reflexiones luego de cinco meses con .Net Core

En enero comencé a trabajar un en proyecto para el sector financiero utilizando .Net Core y me parece que este es un buen momento para compartir algunas sensaciones y hallazgos.

Antes que nada debo decir que hasta 2009 mi carrera profesional estuvo muy vinculada a tecnología Microsoft en general y a .Net en particular. En 2009 di un vuelco en mi carrera y empecé a involucrarme más de cerca con otras tecnologías. Fue así que hice varios proyectos con Java y Ruby y algunos otros más escasos con NodeJS, Python y C++. Este transitar por variadas tecnologías me resultó muy enriquecedor y revelador. Entre otras cosas descubrí que es posible desarrollar software sin estar completamente atado a un IDE particular y a la infraestructura. Tradicionalmente en .Net uno «vivía» atado a Visual Studio y al Internet Information Server.

Ahora sí, hablemos de .Net Core. Quiero referirme en particular a tres puntos: Experiencia del desarrollador, Stack de herramientas e Infraestructura.

Experiencia del desarrollador

El primer punto a destacar aquí es el desarrollo multiplataforma, .Net core está disponible para Windows, Linux y MacOS (justamente en mi equipo tenemos gente trabajando en las 3 plataformas). [1]

El otro punto destacable es la posibilidad trabajar con .Net Core desde la línea de comandos a partir de un CLI que ofrece funcionalidades de scaffolding, ejecución de tests y posibilidades de extensión. Hay que decir que si bien es posible hacer muchas operaciones desde la línea de comando, no todas están lo suficiente documentadas y como dicen algunos miembros de mi equipo: «hay que aprender los conjuros».

Estos dos puntos hacen que la experiencia de desarrollar con .Net Core sea mucho más parecida a la experiencia del desarrollar con NodeJS, Ruby o Python.

Finalmente hay que destacar las nuevas interfaces de Asp.Net Core que posibilitan el desarrollo de aplicaciones más testeables y el uso de TDD de punta a punta.

Stack de herramientas

Si bien siempre me gusto C# como lenguaje el stack de herramientas me parecía muy limitado, sobre todo luego de trabajar en Ruby. Tradicionalmente el desarrollo a nivel profesional con .Net obligaba al uso de Visual Studio. Hoy en día con .Net Core existen varias alternativas al tradicional Visual Studio, muchas de ellas desarrolladas/soportadas por la iniciativa Omnisharp y entre las que se destacan varios «IDEs livianos» como VSCode, Sublime y Atom. El propio Microsoft viene dando mucho impulso a VSCode el cual tiene una particularidad que lo destaca por encima del resto de los IDEs de su categoría: la capacidad de debugging. Dado que .Net Core aún no ofrece un debugger de línea de comandos el hecho de que el IDE ofrezca un debugger es un punto relevante.

Personalmente intenté trabajar con VSCode y no me resultó cómodo, pero debo destacar que varios miembros de mi equipo (los que viven en Linux) lo vienen utilizando y están conformes.

La herramienta que yo vengo utilizando es Rider, el IDE multiplataforma para desarrollo .Net que perteneciente a la familia de IDEs de JetBrains. Este hecho es una de las cosas que me inclinó a usar Rider ya que en los últimos años yo venía utilizando IntelliJ (Java) y RubyMine (Ruby). Las tres herramientas son muy parecidas y a mi parecer excelentes.

Infraestructura

El hecho de ser multiplataforma despegó completamente a .Net Core (o más precisamente a Asp.net Core) del Internet Information Server. Aquí es donde aparece Kestrel, el web server multiplaforma de Asp.Net Core. Una particularidad de Kestrel es que puede ser instanciado vía código dentro de cualquier aplicación .Net Core. Esto mejora mucho la experiencia desarrollo, testeabilidad de las aplicaciones web y el empaquetamiento/distribución de aplicaciones Asp.Net Core. En relación a este último punto hay mucha información y recursos respecto a distribuir aplicación Asp.Net Core con Docker, de hecho hay imágenes Docker de Net Core y Asp.Net oficiales provistas por Microsoft.

En nuestro proyecto estamos usando Docker y nuestra aplicación corre Dockerizada dentro de Kubernetes.

[1] Hay que mencionar que previo a .Net Core hubo varios iniciativas (Mono, Xamarin, etc) para proveer algunas de las caraterísticas que menciono en este artículo, pero a mi parecer dichas iniciativas no lograron no llegaron al mainstream, aunque sin duda fueron motivadores del nacimiento de .Net Core.

¡LLegamos a producción!

Hace unos días comenté que teníamos el desafió de llegar a producción en 8 días con una aplicación construida desde cero.

Ayer cumplimos el objetivo.

En el camino nos encontramos con varios imprevistos relacionados principalmente con las aplicaciones existentes con las que teníamos que interactuar. Cuestiones principalmente de networking, seguridad y accesos. Todas cuestiones que intentaremos ir puliendo en las próximas iteraciones.

El siguiente gráfico resume la arquitectura productiva de nuestra aplicación:

Nuestra aplicación consiste en un frontend construido con Angular (servido por Nginx) y un backend construido con Net Core (aspnet/kestrel) que consume servicios WFC/SOAP que proveen acceso al core de la organización. Tanto front como back son empaquedados en imágenes docker que luego corren en Kubernetes. Dentro de Kubernetes tenemos pods de front y pods de back que en ambos casos corren en un esquema de sidecars con filebeat. Esto es: cada pod corre dos contenedores, uno con nuestra aplicación (front o back) y uno con filebeat que se encarga de leer los logs escritos por nuestra aplicación y mandarlos a Elastic/Kibana para tener así un acceso centralizado al log. Por otro lado, por fuera del cluster Kubernetes hay un conjunto de dispositivos de red (routes, balancers, firewalls, etc) y servidores de distintos tipo donde corren los servicios con los que interactua nuestra aplicación.

En próximos post compartiré algunos detalles de nuestra forma de trabajo y nuestro pipeline de delivery.

Nuevo proyecto, nuevos desafíos

Nuevo proyecto, nuevos desafíos

Esta semana estoy arrancando formalmente un nuevo proyecto. La semana pasada hicimos el descubrimiento de producto y como parte del mismo identificamos objetivos de negocio y métricas para medir el éxito. También definimos algunas cuestiones de estrategia tanto técnica como de negocio.

Entre los desafíos del proyecto hay algunas cuestiones que me parece relevante mencionar:

  1. Un equipo de desarrollo distribuido en 2 ciudades y conformado por personas de 4 organizaciones distintas.
  2. El uso de un conjunto de tecnologías de desarrollo (.net core y angular) en las que la mayoría del equipo no tiene experiencia.
  3. El uso de una infraestructura de ejecución (docker y kubernetes) en la que la mayoría del equipo no tiene experiencia.
  4. La necesidad de generar un entregable de valor en un tiempo máximo de 6 semanas.
  5. La integración con una aplicación legacy.
  6. Requerimientos concretos de accesibilidad.
  7. El uso de ciertas prácticas de desarrollo de cara a intentar asegurar la calidad del entregable (continuous delivery, test-automation, infra as code, etc)

Mi participación en el proyecto tiene que ver principalmente con ayudar en los puntos 2, 3 y 7.

Como parte del trabajo de discovery (que duró 3 días) generamos también algunos acuerdos de trabajo:

  • Trabajaremos en iteraciones de 2 semanas
  • El jueves será el día de las ceremonias de planning/review/retro
  • La daily standup será 9.30
  • El trabajo lo organizaremos en Jira
  • Para la comunicación diaria utilizaremos Microsoft Teams
  • Para el código utilizaremos GitLab
  • Jenkins será nuestro Build Server

Me gusta mucho que la daily sea tempranito pero no me gustan tanto las iteraciones de 2 semanas, sinceramente prefiero iteraciones de 1 semana, pero en bueno, es algo con lo que puedo vivir.

A medida que el proyecto vaya avanzando iré compartiendo novedades en este espacio.

No más .dlls en Git: infraestructura de desarrollo .Net

Una y otra vez me encuentro con equipos de desarrollo trabajando con tecnología .Net que guardan .dlls (librerías/packages) en repositorios de código fuente. Esto fue una práctica común en una época (lejana) y que yo mismo utilicé en algún momento. Pero desde la aparición de NuGet la gestión de librerías en en mundo .Net tomó un camino distinto.

Cuando uno tiene una dependencia de una librería a nivel binario, simplemente declara la dependencia en un archivo package.json y la herramienta NuGet se encarga de buscarlo en el repositorio binario y descargarlo. NuGet por default busca las librerías/paquetes en https://www.nuget.org/. Sin embargo hay dos casos donde seguramente no encontremos la librería en este repositorio:

  • Si estamos usando librerías de terceros, puede que por algún motivo esos terceros no hayan publicado el correspondiente paquete en nuget.org y dependiendo del tipo de licencia del paquete puede que no tengamos derecho a publicarlo nosotros mismos en un repositorio abierto.
  • Por otro lado es muy común hoy en día con el auge de los microservicios que uno tenga librerías propias que utilice en diversos proyectos de la organización y a menos que nuestros proyectos sean open source, es poco probable que querramos publicar esas librerías en nuget.org

Entonces, para estos dos casos la estrategia a seguir es utilizar un repositorio privado de binarios ya sea on-prem (instalando por ejemplo un Nexus) o utilizando algún servicio en la nube (como por ejemplo myget).

Si ponemos todo esto en contexto, una arquitectura de desarrollo de referencia podría incluir:

  • Un servidor de repositorios de código fuente, por ejemplo alguna implementación de Git como GitHub, GitLab o BitBucket.
  • Un servidor de CI/CD como Jenkins o TeamCity
  • Un servidor de repositorios de binarios NuGet como Nexus, MyGet o Artifactory

Developing .Net on Mac

Developing .Net on Mac

I am not talking about .Net Core that runs on MacOS out-of-the-box. I am talking about .Net Framework 4.5 that only runs on Windows. This means that you need a Windows installation.

One option is to install Windows directly on Mac hardware, but this was never an option for me.

So the other option is to virtualize Windows. But this option implies 2 more concerns: which virtualization technology to use and which Windows version to virtualize.

Regarding virtualization I am using Oracle Virtual Box, it is free, works fine and I have been using it for years, so I didn’t even try other tool.

Regarding Windows, I tried different options and finally I decided to use what  worked best for me: Windows 7 (64 bits) but with an «special setup»: no antivirus and updates turned off.

And finally, beyond Visual Studio and the usual stuff for .Net development I added the following software:

  • Cmder, a great console emulator
  • Notepad++, a lightweight file editor
  • FireFox, the browser

 

No more System.IO.File

If you are working with .Net and you need to read/write files you may be familiar with the System.IO.File class which provides many methods to manipulate files. But there is an issue with that class: its methods are static and because of that you won’t be able to mock it*.

After dealing with this situation for several years and using always a very similar strategy, I finally decided to create a reusable component to encapsulate the System.IO.File class.

The component I created is called System.IO.Utilities, its code is available on Github and it is also published on NuGet, ready for you to use it. At this moment it just provides an interface with one implementation that wraps the System.IO.File class.

Here you can see how to use it.

Contributions are welcome 😉

(*to be more precise: you won’t be able to mock that class with proxy-based mocking tool like Moq, but you can still mock it with «lower-level» tool like TypeMock)

Refactoring .Net applications: How-to NuGet

 

Let’s say you have two .Net applications: A and B and a shared component C. From a source code versioning point of view you could have:

  1. RepoFor(A, B, C)
  2. RepoFor(A, B) and OtherRepoFor(C)
  3. RepoFor(A, C) and OtherRepoFor(B)
  4. RepoFor(B, C) and OtherRepoFor(C)
  5. RepoFor(A)  and RepoFor(B) and RepoFor(C)

Except for scenario (1), all the other scenarios would require to clone more than repo, and at the same you could have additional issues when dependencies AC and BC are established at source code level.

The «elegant way» of solving this situations is to establish the dependency at binary level, that is: A and B should depend on C.dll not on C source code. So to do that you need NuGet.

NuGet is a package manager for .Net that will allow to publish packages containing .dlls (and some other stuff too).

The following diagram illustrates the suggested solution:

nuget

Here are 2 short videos I recorded to show how to create and publish NuGet packages.

 

NetConfUY 2016, día 3

NetConfUY 2016, día 3

La jornada comenzó con una charla no tan técnica de Alvaro Lame (un referente de la industria uruguaya de software) quien habló sobre la actualidad y los desafíos de la economía digital en Uruguay. La exposición fue muy buena y con un montón de datos interesantes.

A continuación Diego González y Lucas Pallarés dieron una sesión de programación sobre Hologens y codearon un juego en 40 minutos, impresionante. La sesión fue interesante y arriesgada pero todo salió impecable.

En el siguiente bloque escuché a Mariano Vazquez hablando sobre micro-servicios. Comenzó explicando los fundamentos y luego compartió varias de sus lecciones aprendidas en el día a día con este tema.

Ya cerrando la mañana Victor Silva habló sobre DevOps, PowerShell y Windows Containers. Esta fue una de las sesiones que me resultó más útil, ya que no estaba al tanto de varias de las cuestiones mencionadas y al mismo tiempo resultan ser todas cosas aplicables a mi proyecto actual. No voy a entrar en mayor detalle sobre la sesión pero les dejo algunas «keywords» para googlear: Windows Nano Server y PowerShell DSC.

Luego del almuerzo estuve rondando de un lado a otro haciendo sociales. En ese contexto estuve hablando con Dalmiro Granias, un desarrollador del equipo de Octopus y con Kevin Pilch, del equipo de C# en Microsoft.

Ya en el último bloque de la tarde escuché a Hernán Guzmán hablando sobre Serverless Computing usando Azure Functions (un análogo a Webtask de Auth0). Como la sesión terminó un poco antes de lo planeado, llegué a ver el cierre de la sesión de RodolfoF sobre Asp.Net Core, un tema con el cual vengo experimentando desde hace un tiempo y que sin dudas es uno de los temas calientes en la actualidad del mundo .Net.

La jornada finalizó con un after en el que compartimos empanadas, cerveza y música con la compañía de un mago que nos entretuvo con muy buenos trucos con cartas y sogas.

NetConfUY 2016, día 2

El día comenzó con el Keynote de Edu Mangarelli, como siempre, un excelente orador. Su keynote rondó alrededor de 3 temas calientes: Machine Learning, Bots

A continuación Gabriel Cor habló sobre Hologens, entre anécdotas y chistes contó un algunos casos del uso de Hologens en proyectos reales. Muy interesante.

El siguiente bloque de charlas estuvo dedicado a servicios cloud: primero MatiasQ habló sobre Azure Search y luego Tony Poza habló sobre Cognitive Services. Dos temas interesante que habilitan (o facilitan muchísimo) la resolución de ciertas situaciones.

Ya por la tarde Mariano Sanchez habló sobre TypeScript, la charla comenzó bien, pero me fui antes del final porque para mi gusto TypeScript intenta «mejorar JavaScript» pero paradójicamente «le quita a JavaScript» las cuestiones que más me gustan. En fin, más allá de esta cuestión de gustos, la sesión de Mariano estuvo muy bien (al menos la parte que escuché). La siguiente sesión fue muy útil e interesante: Kevin Pilch habló sobre el futuro de C#. Mi evaluación de los futuros cambios de C# tiene resultado «neutro» en el sentido que la mitad de las cosas me gustaron mucho mientras que la otra mitad me parecieron «aterradoras».

En el siguiente bloque estuve «saltando» de una sala a otra y la verdad no puedo opinar sobre las sesiones.

Ya en el último turno estuve en la sesión de Azure Stream Analytics de Leo Micheloni. Me gustó mucho que además de explicar el producto, Leo compartió varias recomendaciones consecuencia de su experiencia real con el producto.

Y así se fue el día 2.

NetConfUY 2016, día 1

NetConfUY 2016, día 1

El primer día de la conferencia estuvo dedicado por completo a workshops, dos tracks en paralelo, con sesiones de 2 horas para poner manos en la masa. Dado que las sesiones tenían un cupo de 40 asistentes la cantidad total de gente de este primer día estuvo acotada. Resumo brevemente las sesiones a las que yo asistí.

La primera sesión fue Prototipado de aplicaciones Moviles con Xamarin Forms y estuvo a cargo de Sorey García. Este es uno de los temas con los que me sentía en deuda y por ello decidí asistir. El contenido no fue muy profundo pero para mi que estaba totalmente en cero, me vino de muy bien. Con lo que vi creo que ya tengo una idea suficientemente para imaginar los casos específicos en los que Xamarin podría resultar la opción apropiada.

Mi segunda sesión del día fue IoT para principiantes: Mis primeros pasos con Arduino y fue facilitada por Leo Micheloni. Este es otro de los temas que tenía pendiente hace muchísimo tiempo. La sesión estuvo excelente, los asistentes nos repartimos en varias mesas (entre 4 y 6 por mesa) y Leo nos repartió un kit de Arduino y unos pendrives con el SDK para instalar. Inicialmente hizo una explicación general y luego pusimos manos a la obra armando distintas configuraciones sobre la plaqueta y programando distintas «lógicas» usando: leds, pulsadores, sensores de proximidad, etc, etc. El modelo de programación y «ensamble» de Arduino es realmente muy simple.

Las sesiones 3 y 4 fueron como «hermanas»: primero Asp.Net & ReactJS y luego Asp.Net Core & Angular 2. Estas sesiones estuvieron a cargo de Mariano Vazquez y Nico Bello respectivamente (dos miembros de la familia FIUBA, ¡que chico parece el mundo a veces!).  Desde el punto de vista del contenido y la dinámica, ambas sesiones estuvieron muy bien.

Ya cerrando el día participé de la sesión de MauroG y RodolfoF sobre Asp.Net Core en Linux. La sesión estuvo bien pues el ejemplo sobre el que se trabajó cubrió la un caso web típico de punta a punta: UI-Controllers-Models-DB.

Al finalizar la última sesión, ya eran más de las 21, ¡upa! vaya que fue un día intenso y aún quedan dos días más  😉