Archivo de la etiqueta: NET8

Desarrollando en .NET para la versión 2024 de Digi3D.NET

Hoy día 8 de enero de 2024 hemos publicado la versión 2024 de Digi3D.NET.

Esta versión viene cargada de novedades, y si eres desarrollador hay una que te va a afectar: El programa hora no es compatible con .NET Framework, sino que lo hemos portado a .NET 8.0.

Si has desarrollado alguna extensión para el programa o si has desarrollado algún programa de consola utilizando los ensamblados de Digi3D.NET, tendrás que portarlos de .NET Framework a .NET 8.0.

Para portar tus aplicaciones tan sólo tienes que instalar en Visual Studio 2022 la extensión .NET Upgrade Assistant, cargar tu proyecto y en el explorador de soluciones pulsar el botón derecho del ratón y seleccionar la opción de Upgrade. Aparecerá un asistente que migrará tanto los archivos de proyecto (actualizando paquetes NuGet, moviendo información que antes estaba en el archivo AssemblyInfo.cs al propio archivo de proyecto, etc.

Una de las diferencias más importantes entre .NET Framework y .NET es que ya no existe el Global Area Cache.

Cuando instalas en tu aplicación cualquiera de los paquetes NuGet que proporcionamos para desarrollar extensiones o aplicaciones:

Lo que instalas realmente es un Ensamblado De Referencia, es decir: un ensamblado que no tiene código ejecutable, únicamente tiene declaraciones de tipos, con sus propiedades, métodos, etc., pero sin código.

Cuando se instala una versión anterior de Digi3D.NET, el instalador almacena en el Global Area Cache los ensamblados de runtime (estos sí que tienen código) equivalentes.

Cuando ejecutas tu aplicación compilada con los ensamblados de referencia, el cargador de CLR de .NET Framework ve que tu aplicación depende de un ensamblado, por ejemplo: Digi21.DigiNG, versión 23.0.0.0, lo busca en el Global Area Cache y sabe que este está implementado por una DLL denominada Digi21.DigiNG.dll y la carga en memoria.

En Digi3D 2024 hemos seguido con la misma lógica: Los paquetes NuGet publican ensamblados de referencia y únicamente actualizamos estos paquetes NuGet cuando ha cambiado algo en la superficie pública de estos ensamblados. Si se modifica el programa por cualquier motivo (en el año 2023 hemos publicado en el canal BETA más de 140 versiones del programa) y dicha modificación no realiza ninguna modificación en la superficie pública de estos ensamblados, no es necesario actualizar los paquetes NuGet: el usuario actualiza la aplicación y tus herramientas siguen funcionando.

Pero conseguir que todo esto funcione de una forma transparente como con las versiones de .NET Framework no ha sido nada sencillo y te lo explico a continuación. Si no quieres entrar en detalles, mira el vídeo de abajo del todo y porque a partir de ahora me pondo un poquito más técnico:

.NET está pensado para que cargues en tus proyectos paquetes NuGet, que idealmente tienen o un único ensamblado de runtime o un ensamblado de referencia y múltiples ensamblados runtime (que implementan lo indicado en dicho ensamblado de referencia, como, por ejemplo, una versión específica para .NET Core 3.0, otra para .NET 5, otra para .NET 6, otra para Linux, otra para Mac, otra para Windows 10…).

Cuando el compilador se encuentra con un paquete NuGet de alguno de los dos casos indicados en el párrafo anterior (es decir que tienen al menos un ensamblado de runtime), almacena en el archivo .deps.json de la aplicación compilada una entrada denominada «runtime» en la que indica el nombre de la DLL a cargar.

El 100% de los paquetes que he visto en NuGet.org son así. Como todos tienen ensamblados de runtime, el compilador de manera automática rellena esa información en el archivo .deps.json.

Pero nuestros paquetes no tienen ensamblados de runtime, de manera que cuando se compilaba con las versiones alpha de nuestros paquetes NuGet para .NET 8.0, las aplicaciones no incluían en el archivo .deps.json información de runtime y el cargador del CLR no sabía qué DLL cargar.

Para solucionar esto, ahora todos los nuestros paquetes NuGet añaden un PostBuildEvent que modifica el archivo .deps.json de la aplicación compilada, añadiendo en caso de que no exista ya, una entrada runtime en la que se indica el nombre de la DLL que implementa el ensamblado.

Si te interesa cómo está hecho, he publicado en mi GitHub personal un repositorio en el que lo explico en detalle: https://github.com/joseangelmt/AddRuntimeToDepsJson

Y por último: si lo que has hecho no es una extensión para Digi3D.NET sino que es una aplicación que utiliza los ensamblados publicados por Digi3D.NET, como por ejemplo el ensamblado Digi21.DigiNG.IO.BinDouble, si no copias tu programa en el mismo directorio que la aplicación principal, no se va a localizar la DLL: Digi21.DigiNG.IO.BinDouble.dll, que es la que implementa dicho ensamblado.

Para solucionar esto, podemos añadir un nodo additionalProbingPaths en el archivo .runtimeconfig.json de tu programa indicando la ruta de instalación de la aplicación principal.

Para evitar tener que hacer esto manualmente, hemos creado el paquete NuGet: Digi21.Digi3D.App que lo único que hace es añadir un PostBuildEvent que añade al archivo .runtimeconfig.json de la aplicación compilada, en el nodo additionalProbingPaths una entrada al directorio de instalación de Digi3D.NET, y con esta entrada ya sí que podemos ejecutar nuestro programa desde cualquier directorio.
Tienes publicado el código de este paquete NuGet en el siguiente repositorio: https://github.com/digi21/Digi21.Digi3D.App

A continuación, un vídeo explicando todo esto de una manera sencilla: