Developing in .NET for the 2024 version of Digi3D.NET

January 8, 2024 NET8

Today 8 January 2024 we have released version 2024 of Digi3D.NET.

This version is packed with new features, and if you are a developer, one will affect you: the application is now incompatible with .NET Framework, as we have ported it to .NET 8.0.

If you have developed an extension for the application or a console application using Digi3D.NET assemblies, you will need to port it from .NET Framework to .NET 8.0.

To port your applications, just install the .NET Upgrade Assistant extension in Visual Studio 2022, load your project, right-click it in Solution Explorer, and select Upgrade. A wizard will migrate the project files (updating NuGet packages, moving information previously stored in AssemblyInfo.cs into the project file itself, etc.

One of the most important differences between .NET Framework and .NET is that the Global Area Cache no longer exists.

When you install in your application any of the NuGet packages that we provide for developing extensions or applications:

What you actually install is a Reference Assembly: an assembly with no executable code, containing only type declarations and their properties, methods, etc., but no code.

When you install an earlier version of Digi3D.NET, the installer stores the equivalent runtime assemblies (which do contain code) in the Global Area Cache.

When you run your application compiled with the reference assemblies, the .NET Framework CLR loader sees that your application depends on an assembly, for example Digi21.DigiNG, version 23.0.0.0. It looks for it in the Global Area Cache, knows that it is implemented by a DLL called Digi21.DigiNG.dll, and loads it into memory.

In Digi3D 2024, we have followed the same logic: NuGet packages publish reference assemblies, and we only update those NuGet packages when something changes in those assemblies' public surface. If the application changes for any reason (in 2023, we published more than 140 versions on the BETA channel) without changing the assemblies' public surface, there is no need to update the NuGet packages: the user updates the application, and your tools keep working.

Getting all of this to work transparently, as it did with the .NET Framework versions, has been far from easy, as I explain below. If you do not want the details, watch the video at the very bottom, because things get a little more technical from here:

.NET is designed for you to load NuGet packages into your projects. Ideally, these contain either a single runtime assembly or a reference assembly and multiple runtime assemblies (which implement what the reference assembly specifies, for example a version for .NET Core 3.0, another for .NET 5, another for .NET 6, another for Linux, another for Mac, another for Windows 10...).

When the compiler encounters either type of NuGet package described above (that is, one with at least one runtime assembly), it stores a "runtime" entry in the compiled application's .deps.json file specifying the name of the DLL to load.

Every package I have seen on NuGet.org works this way. Because they all have runtime assemblies, the compiler automatically fills in this information in the .deps.json file.

Our packages, however, have no runtime assemblies. When compiling with the alpha versions of our NuGet packages for .NET 8.0, applications did not include runtime information in .deps.json, so the CLR loader did not know which DLL to load.

To solve this, all our NuGet packages now add a PostBuildEvent that modifies the compiled application's .deps.json file, adding a runtime entry with the name of the DLL that implements the assembly if that entry does not already exist.

If you are interested in how it is done, I have published on my personal GitHub a repository in which I explain it in detail: https://github.com/joseangelmt/AddRuntimeToDepsJson

Finally, if you have created an application that uses the assemblies published by Digi3D.NET, such as Digi21.DigiNG.IO.BinDouble, rather than a Digi3D.NET extension, the DLL implementing that assembly, Digi21.DigiNG.IO.BinDouble.dll, will not be found unless you copy your application into the main application's directory.

To solve this, you can add an additionalProbingPaths node to your application's .runtimeconfig.json file with the main application's installation path.

To avoid doing this manually, we created the Digi21.Digi3D.App NuGet package. It simply adds a PostBuildEvent that adds an entry for Digi3D.NET's installation directory to the additionalProbingPaths node in the compiled application's .runtimeconfig.json file. With this entry, you can run your application from any directory.
The code for this NuGet package is published in the following repository: https://github.com/digi21/Digi21.Digi3D.App

Here is a video explaining all this in a simple way:


Back to the blog