A lot of us still have a ton of C/AL code sitting around in existing databases that sooner or later will have to be moved into AL. A lot of us also have a ton of AL code using DotNet that we want to be able to run in Microsoft’s cloud (that is: not on-prem). And I guess most of us don’t want to maintain a DotNet-less and DotNet-ful versions of our code.
Sooner or later, you’ll want all of DotNet out of your AL. Even if you are a seasoned .NET developer, you’ll want all DotNet out of AL.
Anyway, when you need to replace DotNet, what options do you have? Let’s take a look at all possible paths.
1. Native AL types and code
What do you know, a lot of us used .NET and then wrapped it into DotNet out of sheer laziness, or coolness, or somethingelseness. It was great to write in C#, compile, deploy, then use it, because perhaps it was faster, or perhaps simpler to write in C# than C/AL, or… whatever your reason was.
A lot of times a lot of that you can simply rewrite in AL, and it would still work. If you use DotNet to perform things that AL can do all the same, then just do it in AL.
Using a DotNet collection for what you could have used a temporary table? Switch to temporary table. Doing some fancy calculations. AL may be able to do it natively.
Then maybe there are situations where you may prefer a total change of paradigm. An example I’ve seen recently: a developer used DotNet to retrieve image format information from an image uploaded into the database, so that correct data URI can be specified when showing that image in a control add-in. No native types exist here, and any solution you reach for may be far too complicated. Add an extra field to store image format, and use that field when you need it. Maybe not the best or the most foolproof solution out there, but for most situations good enough.
2. New AL Types
A lot of DotNet types now exist as AL types. Needless to say, when you have such a DotNet type in AL, just replace the code with the matching AL type.
Most used Newtonsof.Json types, most of Dictionary`2 or List`1 instances, most of System.Xml types, StringBuilder, System.String methods, all of this now exists as AL types. All of web service invocation now works natively in AL. If you can use them, you should use them.
Sure, there are exceptions to this. If you had a Dictionary<string, IFoo>, or you need JsonProperty, or static string methods, or… Yeah, there are a lot of those that just don’t exist in AL (yet). If you are unlucky enough that you have those, and can’t use built-in AL types, you need to reach for another option.
3. DotNet_* Codeunits and other standard objects
Business Central Base App includes a lot of codeunits named DotNet_*. There are 45 of those as of the 2020 Wave 2 release. If neither of the previous two approaches works for you, check if there is a codeunit here that could help you.
Just a few examples: regular expressions, binary reading and writing, text encoding, date/time formatting, etc. I myself haven’t used much from this list, but I think I am right to assume that those codeunits are there to replace the most commonly used DotNet types, and therefore you stand great chances of finding your solution here.
Then, there are other standard objects now that can help you solving the problems DotNet solved for you before. Base64 encoding, data compression, web services, and a lot more don’t require any DotNet on your end anymore.
Still not solving your problem? There are more options.
4. Azure Functions or some other serverless approach
If you have your .NET logic inside an assembly that you use through DotNet in AL, then Azure Functions are extremely simple. If you have a C# solution, simply add a new C# Azure Functions project to it, reference your original assembly, and write a simple RESTful façade for each of your public methods.
The downside here is additional latency, however when running in Azure hosted environments (which is where Microsoft hosts all of Business Central anyway) you won’t suffer from much latency.
Another issue may be cold starts. Yes, if your Azure Function app is not running, it will take a short while to load it. But you can address this in various ways. You can have a keep-alive script that pings your function every so often to make sure Azure doesn’t recycle it away. This is not guaranteed to work (if you have huge load demand, Azure may decide to spawn and specialize another runtime instance, which will suffer from the same cold-start issues), but in many situations this may be the cheapest solution. If you demand reliable and fast availability of your functions, and have extra buck to spare, durable functions may be the answer.
In any case, this may be the best option you have if none of previous ones work. But we have more.
5. Web Assembly
If your functionality is mission-critical and serverless latency is going to be a problem, you can move your code into a web assembly and host it in a control add-in. If you haven’t heard of Blazor, then now is the time you did. It’s Microsoft’s project that allows you to run C# code from web assemblies in your browser, platform-independent. How much cooler can it get?
Yes, you have to build your web assembly, and wrap it into a control add-in, and then make sure it’s available when you need it, even when you are not inside a dedicated page that runs the control add-in, but all of these are problems with simple solutions. This extra pain it puts you through is totally worth the show you can get out of this. I’ve seen people put crazy things into their web assemblies and then use them from BC. A guy embedded Unity Web Player to run some kick-ass 3D visualizations, all inside Business Central Web Client.
Finally, there is this repo on Microsoft’s GitHub: http://github.com/Microsoft/ALAppExtensions/
They have a nice Readme file and there is a whole step-by-step guide at aka.ms/NewALModule, but TL;DR this allows you to create your own codeunit wrappers around any .NET Framework feature and make it a part of the System App through a pull request. Now we are truly talking open-source Business Central!
There are catches, here, of course. Microsoft cannot guarantee that they will accept your PR. If it’s good and well-written and follows all the standards, most likely they will include it, though. Another catch is that you don’t get it *now*, and *now* is when most customers need things. With any of the approaches above, you can do it *now* and deploy it to your customers right away. With this approach it will take a while.
Still, open source… Wow! Just wow!
As you can see, there are many ways you can replace your DotNet with something else. The fact that you cannot run DotNet in Microsoft’s cloud doesn’t mean you cannot get your app certified for AppSource. You absolutely can. Yes, it will take some effort, but it will be worth it, and you’ll be glad you did it.
Do you know of another way to replace DotNet with something else in AL? Don’t be shy, share it in the comments section.
And remember: DotNet? Don’tNet.