'C# .NetCore .NetFramework .NetStandard: el bueno, el feo y el malo'
22-07-2024
Hoy venimos a exponer una conclusión a la que he llegado, con la finalidad de evitar posibles cosas raras, cuando estamos manejando distintos proyectos en C# con un “target” distinto.
Me explico, para todas aquellas personas que no conozcan del entorno C# y sus variedades, dentro de este lenguaje de programación, existen dos grandes frameworks:
- NetFramework: Es la implementación “antigua” del framework. Solamente está disponible para ejecutarse en plataforma Windows.
- NetCore: Es la implementación “moderna” del framework. Es multiplataforma, es decir, se puede ejecutar en Linux, Windows y Mac.
- NetStandard: Es el conjunto de interfaces que conforman el framework. Se usa para compartir base de código entre ambas implementaciones mencionadas previamente.
Problema
Ahora dirás, vale Jorge, ¿qué problema hay con esto que has comentado?. Si Microsoft ha diseñado esto así, pues será por algo y no debería haber conflicto con esto.
Resulta que el problema viene cuando tienes un proyecto en .NetStandard y hacemos uso de esas implementaciones concretas de .NetCore o .NetFramework, ya que cada una de esas implementaciones, según que versión, lanza una excepción u otra. Sí, ¿un poco locura verdad?
Veamos un ejemplo más concreto
Imaginemos que en tu código de .NetStandard haces uso del HttpClient
y que
quieres hacer reintentos en caso de que haya un error de red. Pues ahora bien,
dada esta situación, la excepción que resulta en un error de red, difiere según
que framework usemos, es decir, está acoplada a la implementación concreta del
framework que estemos usando en ese momento.
La problemática de esto, deriva en una especie de “código defensivo”, para tratar de cubrir todas las posibles opciones que tenemos para cubrir ese “error de error”, ya que ese código en .NetStandard podrá ser usado en cualquiera de las implementaciones del framework que tenemos.
La cosa se pone más divertida todavía cuando nos ponemos a hacer testing sobre este tipo de “artefacto” en .NetStandard. Puesto que no podemos crear un proyecto de testing para .NetStandard, tenemos que crearlo para .NetFramework o para .NetCore. ¿Creamos pues, un proyecto de test para cada una de las versiones en las que este código vaya a ser ejecutado? ¿O nos conformamos sólo con una de ellas y asumimos que la otra implementación funciona?
Propuesta
Mi propuesta para tratar de evitar este problema, es que cualquier código que tengamos escrito en .NetStandard sea puramente de dominio, para así, reducir al máximo cualquier dependencia con cosas concretas del framework, y de esta manera, evitar quebraderos de cabeza pensando en qué implementación del framework usemos.