The Universal Code Initiative and SaaS related cases

Guidelines for Partners

This article will explain the Universal Code Initiative, and its goals and will enlighten you about the most popular breaking changes regarding Cloud development.

 

Universal Code Initiative aims for better solutions so that code can live in any target environment. The new Business Central Universal code initiative is a modern independent software vendor (ISV) approach to ensure that all future customers can choose Dynamics 365 Business Central online while finding the right apps on Microsoft AppSource to meet their unique requirements. BC on-premises customers who aren’t licensing ‘universal code’ (cloud-optimized extensions) will be affected by gradually increasing fees from 2023 onwards (Dynamics 365 Business Central Universal code initiative | Dynamics 365 Lab).

 

Microsoft has introduced us to two new Modules:

  • Module “Implemented code is not in extensions” – necessary for code customized base apps.
  • Module “Implemented code is not cloud-optimized” – code is in extensions, but that code could only work OnPrem.

Partners that have code working only OnPrem will have to buy a license.  The fee for that license is a per-user per-year fee, which increases every year. You can check fees in the following table:

 

Universal Code Initiative

Official source, slides and Q&A: Microsoft presents: UCI update and FY23 ISV Investment Program

 

This price is “per full user.” The more users you have, the more costly it will be to run your legacy code. If you’re a large company with, say, a 100-user license, that means, in three years, you will be paying as much as $42500 annually just to run outdated code. However, this will not affect customers who licensed BC OnPrem before April 1, 2022.

Let’s talk about requirements while creating extensions to keep code Universal:

  • No code customization in the BaseApp.
  • Writing code that does not require “OnPrem” scope.

When you create an Extension, you must set the “Target” in the app.json file to “Cloud” as in the example below.

 

Universal Code Initiative

 

That means that your code should be able to compile in both: Cloud and OnPrem development. Keep in mind there are some groups of functionalities that will not work in a Cloud environment:

  • Local file operations
  • Custom .Net libraries
  • Direct SQL database operations
  • Others

 

In order to rework file operations, you will have to set up BC to use external connectors and work with files in online repositories, such as Google Drive. For custom-created .Net libraries, you will have to use Cloud-approved applications which allow connecting external applications to your BC solution, such as Power Automate (which already contains more than 500 connectors). As you may probably notice, the Base Application still uses some .Net libraries, and why can we not use them in custom extensions? The answer is simple – all of the previously used functionalities containing any .Net libraries have been moved to the new objects so you can manipulate and use them in your extension, e.g. instead of DotNet Regex, which is allowed in OnPrem development and not in Cloud, you can use Codeunit Regex which is already created in Base Application.

 

Here are some frequently used breaking changes and their solutions while switching from OnPrem to Cloud development in Business Central 2022 Wave 1:

 

Table 2000000028 “Table Information”

Issue: Cannot be used for Cloud development

Possible Solution: Use AllObjWithCaption instead

Notes, Examples:

// SPLN1.00 - Start
//TableRelation = "Table Information"."Table No.";
TableRelation = AllObjWithCaption."Object ID" where("Object Type" = const('Table'));
// SPLN1.00 - End

 

Table 370 “Excel Buffer”

Issue: SelectSheetsName procedure not supported in Cloud

Possible Solution: Add excel file to the input stream and call SelectSheetsNameStream instead

Notes, Examples:

// SPLN1.00 - Start
//Sheetname := ExcelBufferTemp.SelectSheetsName(ServerFileName);
FileMgt.BLOBImport(TempBlob, ServerFileName);
TempBlob.CreateInStream(InStr);
Sheetname := ExcelBufferTemp.SelectSheetsNameStream(InStr);
// SPLN1.00 - End

 

Issue: OpenBook procedure not supported in Cloud

Possible Solution: Add excel file to the input stream and call OpenBookStream instead (needs testing)

Notes, Examples:

// SPLN1.00 - Start
//ExcelBufferTemp.OpenBook(ServerFileName, Sheetname);
FileMgt.BLOBImport(TempBlob, ServerFileName);
TempBlob.CreateInStream(InStr);
ExcelBufferTemp.OpenBookStream(InStr, Sheetname);
// SPLN1.00 - End

 

DotNet “Interaction”

Issue: Interaction.InputBox not supported in Cloud

Possible Solution: Recreate analogy creating additional page as a dialog window with a text field. In order to replicate as similar as possible, create group and textfield, create procedures to set their captions and get value, set page type as StandardDialog.

Notes, Examples:

// SPLN1.00 - Start
//ToVersion := Prompt.InputBox(MTxtNewVersionPrompt, MTxtNewVersionTitle, '', 450, 300);
CopyVersion.LookupMode(true);
CopyVersion.Set_VersionCaption(MTxtNewVersionPrompt);
if CopyVersion.RunModal() = Action::LookupOK then begin
ToVersion := CopyVersion.Get_VersionValue();
end;
// SPLN1.00 - End

 

DotNet UTF8Encoding

Issue: Not supported in Cloud

Possible Solution: Use InStream and OutStream to read text using UTF8 encoding

Notes, Examples:

// SPLN1.00 - Start
//SystemUTF8Encoder: DotNet UTF8Encoding;
//SystemByteArray: DotNet Array;
SystemByteArray: Codeunit DotNet_Array;
InStrEncoder: InStream;
OutStrEncoder: OutStream;
TempBlob: Codeunit "Temp Blob";
UTF8EncodedNote: Text;
// SPLN1.00 - End

 

DotNet Array

Issue: Not supported in Cloud

Possible Solution: Use Codeunit DotNet_Array

Notes, Examples:

// SPLN1.00 - Start
//SystemUTF8Encoder := SystemUTF8Encoder.UTF8Encoding;
//SystemByteArray := SystemUTF8Encoder.GetBytes(Note);
TempBlob.CreateOutStream(OutStrEncoder, TextEncoding::UTF8);
OutStrEncoder.WriteText(Note);
TempBlob.CreateInStream(InStrEncoder, TextEncoding::UTF8);
InStrEncoder.ReadText(UTF8EncodedNote);
SystemByteArray.ByteArray(StrLen(UTF8EncodedNote));
for i := 0 to StrLen(UTF8EncodedNote) - 1 do begin
SystemByteArray.SetByteValue(UTF8EncodedNote[i], i);
end;
// SPLN1.00 - End

// SPLN1.00 - Start
//Char1 := SystemByteArray.GetValue(i);
Char1 := SystemByteArray.GetValueAsChar(i);
// SPLN1.00 - End


DotNet Regex 

Issue: Not supported in Cloud

Possible Solution: Use codeunit “Regex” instead

Notes, Examples:

// SPLN1.00 - Start
//RegEx: DotNet Regex;
//RegExOptions: DotNet RegexOptions;
RegEx: Codeunit Regex;
RegExOptions: Record "Regex Options";
// SPLN1.00 - End;

 

DotNet RegexOptions.IgnoreCase 

Issue: Not supported in Cloud

Possible Solution: Use record “Regex Options” instead by setting required parameters and pass where needed

Notes, Examples:

// SPLN1.00 - Start
//RegEx := RegEx.Regex(ErrorMessageAction."RegEx Pattern", RegExOptions.IgnoreCase);
RegExOptions.IgnoreCase := true;
RegEx.Regex(ErrorMessageAction."RegEx Pattern", RegExOptions);
// SPLN1.00 - End;

 


 

In conclusion, as Business Central seems to be moving towards Cloud development, it becomes more and more important to make your code more Universal.

Free Dynamics NAV / 365 Business Central Project Estimate

Submit this form if You want to boost Your Dynamics NAV / 365 Business Central services
Name(Required)
Privacy policy(Required)