With Dynamics 365 Business Central 2021 Wave 1 Microsoft is continuously moving the server to .NET Standard and if you’re using on-premises .NET add-ins that targets .NET Framework, you should start converting them in order to use .NET Standard. .NET add-ins compiled with .NET Framework won’t work in Business Central 2022 release wave 1.
This message was quickly launched also recently and I think that not everyone of you has correctly received this recommendation.
Just to do a bit of clarification, when .NET Framework was shipped (more than 15 years ago if I remember correctly), it had a single .NET stack that you could use for building Windows desktop and Web applications. Later, the .NET implementation has evolved and now, together with the full .NET Framework we have:
- .NET Core: this is the latest .NET implementation. It’s open source and available for multiple OSes. With .NET Core, you can build cross-platform console apps and ASP.NET Core Web applications and cloud services.
- .NET Standard: this is the set of fundamental APIs (commonly referred to as base class library or BCL) that all .NET implementations must implement. By targeting .NET Standard, you can build libraries that you can share across all your .NET apps, no matter on which .NET implementation or OS they run.
The various .NET implementations target specific versions of .NET Standard and I recommend to check the matrix at the following link in order to check the minimum implementation versions that support each .NET Standard version.
What does that means for your .NET add-ins? That you need to do a code check and then upgrade the add-in in order to be .NET Standard compliant. I think that some of your .NET add-ins can be fully compliant or easily portable to be .NET Standard compliant, but for other more complex solutions this process could be instead more tricky.
To start this process, personally I recommend first to analyze your solution and discover the parts of your code that you need to refactor. There are some (not so well-known in my opinion) tools that can help you on this process.
As an example on how to perform this analysis, I’ve used here an add-in that we have on some of our solutions. This is a quite complex add-in that does different things by reading data from Dynamics 365 Business Central and then sending those data to an external service (SOAP-based service hosted by the Italian government). At the moment, this is an add-in that supports .NET Framework 4.6.1 and above:
The above solution contains two projects:
- A class library that handles the communication with Dynamics 365n Business Central
- The add-in core itself (that handles the communicationm with the external service)
How can I analyze my project in order to discover the portability to .NET Standard?
For this, I recommend to install the .NET Portability Analyzer extension from the Visual Studio Marketplace:
The .NET Portability Analyzer is a tool that analyzes assemblies and provides a detailed report on .NET APIs that are missing for the applications or libraries to be portable on your specified targeted .NET platforms.
When installed, you need to configure it in order to define what type of portability analysis you want to have (the target .NET versions that you want to be compatible with). To do that, on Visual Studio select Analyze and then Portability Analyzer Settings:
In the opened window, select your Target Platforms, which are the .NET platforms/versions that you want to evaluate the portability gaps comparing with the platform/version that your current assembly is built with:
Here I’m selecting .NET Standard 2.0 and .NET Core 3.1 versions and I’m specifying that I want a final report in HTML and Excel format. When you’ve defined your settings, click OK.
Now right click the project that you want to analyze and select Analyze Project Portability:
A Portability Analisys Results page is opened with the output reports (in your selected formats).
If you open the report (here I’m using the HTML version) you can see a first line that gives you a percentage of compatibility with each particular target framework:
If you scroll down, you can see the details:
As you can see in these details, this solution has portability problems on using SOAP and also portability problems on using System.Configuration (the way we’re using here to read configuration settings). These are the parts of your code that you need to recreate/refactor in order to be compliant.
As you can see, some incompatibilities are solved if you’re using Platform Extensions, a set of APIs that are shipped as NuGet packages instead of being part of the shared framework.
.NET Standard + Platform Extensions includes the .NET Standard APIs in addition to the Windows Compatibility Pack, which provides many of the .NET Framework available technologies. This is a recommended target for porting your library from .NET Framework to .NET Core on Windows.
This application permits you to analyze single DLLs files with a simple command like:
ApiPort.exe analyze -f MyLibrary.dll
but there’s more. If you have a solution with different projects (dependencies) you can visualize the dependencies between libraries in order to understand which subset of assemblies depend on what and to discover where a complex solution can have portability problems.
To do that, just execute the following:
ApiPort.exe analyze -r DGML -f [directory or your solution]
and when the enalysis is done, you have a DGML file that you can open in Visual Studio (Directed Graph Markup Language (DGML) describes information used for visualization and to perform complexity analysis, and is the format used to persist code maps in Visual Studio):
If you open this file, you can see a diagram like the following:
As you can see here, my add-in solution has two libraries. The D365BCAPILayer library is 100% compliant with .NET standard rules, while EIDNECAConnector library ha some problems (93% compliant) due to SOAP usage. You can also click and see the details:
This is a great way to have a clear portability overview of a complex solution.
A final recommendation/advice: as said before, start working on your .NET add-ins and keep them compliant with .NET Standard. On SaaS, you cannot use .NET add-ins at all, so I think it’s a good moment to start forgotting the old NET add-ins and instead start moving them to a modern and cloud-ready solution (for example, moving them on Azure Functions).
When using Azure Functions, please remember that Functions version 2.x is designed to run on .NET Core 2.2 and version 3.x is designed to run on .NET Core 3.1. By default, function apps created in the Azure portal and by the Azure CLI are set to version 3.x. You can modify this version as needed.
Just FYI, remember also that Azure Functions now also supports running production applications in .NET 5, the latest version of .NET. To support .NET 5, Azure Functions introduces a new isolated process model that runs .NET function apps in a separate worker process outside the Azure Functions host runtime. Decoupling your application from the runtime provides greater compatibility with application dependencies and the new model adds features such as support for custom middleware. Details can be found here (and maybe a day we’ll talk about this in more details).