Organizing your “big PTE” in Micro Services

Plans have changed for tonight. Sorry Rene, we’ll try again on thursday. So at home and time to share the next part of the best practices for Per Tenant Extensions.

And just in time, because when I shared part I last night there was confusion right away on Twitter. Especially about confusing shipping all your modifications as one “big” Per Tenant Extensions with making a monolyth.

Let’s look at Microsoft Windows, or Office. Just because Microsoft packages it as s product does not make the development into a monolyth. You can develop in Modules and ship as a software package.

The “Perfect” Example

It’s already a few years ago that Microsoft took our community by surprise and broke the “Functional App” and the “System Modules” into two extensions.

The Functional App is still a Monolyth. It’s almost impossible to break into modules that compile independently. A few years ago we tried with a few people from the community to do so and failed. Mainly because we lacked the availabilty of enums and interfaces but anyway, the cost of doing it does not weigh up against the benefits and the “big app” stayed big.

The System App is a totally different story. Microsoft developed it as modules that compile individually. You can see this on GitHub.

When we get the product on the “DVD” or create a dependency we can see that even though MSFT makes small modules, they ship a big .app file.

This is also normal in other software frameworks and I’ve seen this also for example when a product like ForNAV is packaged. The fact that design.exe is 75MB does not mean it is coded in one large C# file.

How do you implement this in your PTE Project?

The trick to code in modules and ship as software starts with your folder structure.

Please tell me how many times have you seen this as a “structure” for an AL project:

This is horrible and let’s call this an Anti-Pattern from now on.

The Best Practice is to organize your extension in meaningfull foldernames like this

This is not something I “invented” or Microsoft invented. I actually stole this idea from an Uncle Bob video I saw a few years ago. Aparently other programming frameworks also have a tendency to group code by nerdy categories rather than functional elements.

But with our AL framework we have an extra benefit. I’ve marked that benefit in RED.

You see that my “Big App” has an app.json but my “Core App” also has an app.json.

This allows me to open the “Core” folder separate in Visual Studio Code and compile it as a “Micro Service”.

Every Per Tenant Extension has at least two sub modules. Core and Report Pack. With PrintVis we also have “typical PrintVis things” like Calculation Formula’s and Status Code triggers. This will be different for other vertical solutions.

Reusable modules go into Feature folders with their own App.json that compile separately and can be easily reused. I’ll explain in one of the next posts.

Free Documentation

One of the biggest advantages of this way of organizing your code is that the folder stucture becomes your documentation. You can see exactly what the customer wanted customized without even opening an object.

I’ll dive deeper into this in the next blog where I describe the rules for the “Core” extension. Hopefully tomorrow.

Wait a minute Marije, this is not new is it?

No it is not. This way of working could actually have been done in C/Side already and many of us did.

In C/Side we did not have an app.json. Instead we had a “Version List” for an object and a “Documentation” property for table fields.

Many of us have been working like this “unofficially” for decades and had great business succes. Why should we not keep on doing that.

The “Because we can” Anti-pattern

If you ask me, the biggest Anti-pattern we have these days in the Business Central community is the argument “Because we (finally) can”. And this is costing us very valuable time.

I see great AL developers become PowerShell experts, CI/CD gods and Docker Guru’s and all for no reason whatsoever.

We need to look back at C/Side and take back what made us succesful and stop doing things just because we can without adding value for customers.

This and this alone will solve the capactiy problem we have in our community. It is the elephant in the room that for some reason nobody wants to see.

One Per Tenant Extension to ‘Rule Them All’

Never shy away from a catchy title of your blog right?

So enough said about why we need Design Patterns AKA Best Practices for Per Tenant Extensions, let’s dive into my suggestions.

Rule #1 – As few as possible

If you implement Business Central you should have a close fit to your business requirements. The times when we hacked the base app into anything are gone except for a few rusty brown partners that are allowed to still do so.

On top of the Base App you mix and match AppSource solutions. Typically 1 vertical solution and a few horizontal ones. Like for example PrintVis with ForNAV and Continia as something that everyone would understand.

What you then do with your “Per Tenant Extensions” is essentially defining exceptions on metadata level with a few scripts that you want to execute whenever something happens in the system. “Per Tenant Extensions” are not massive blocks of vertical business processes except in few cases but but as a general rule of thumb.

You may have small processes in your PTE that we would call “features”. In many cases they relate to an interface with this and that or creating an excel sheet that goes somewhere in the organization that is fairly unique to a company. You may however reuse these features in other implementations. Not exactly the same but, you know, as inspiration for starting on the next adventure.

The Anti-Pattern – Many Small Per Tenant Extensions

Design Patterns are often easier to explain by telling how not to do things and/or what can go wrong if you don’t follow them.

The biggest problem with having many smaller Per Tenant Extensions is the lack of overview and manageability. I’ve seen first hand situations where source code got lost, different programming styles were applied, objects ID’s were difficult to manage etcetera etcetera. I am sure you can write something in the comments that also illustrates what can go wrong if you start defining too many PTE’s.

Another challenge that should probably not be a challenge but still is, is performance when extending tables in the Base App or in our case PrintVis multiple times.

Even though Microsoft has done a lot to improve the behaviour, it is still not completely “nice” to have all these extensions and in case of a PTE there is a fair chance you want all “your” fields added to list pages anyway right?

But what about reusability?

This I agree is a problem with a big PTE and I promise I will get back to you on that and we’ll fix it in my next blog or the one after that.

The Exception?

I thought you would never ask. What are the exceptions? There is IMHO only one exception which depends on the Service Level Agreement you have with your customer.

Many customers with a larger internal IT team want to do their “own stuff”. Especially reports.

Off course you can make an agreement with your customer that they can get access to the PTE, but only change report objects, not anything else. This may work to some extent but it ships a bit easier if you create a dedicated “Report Pack” extension that is the responsibility of the customer.

I agree, it is debatable and probably after reading the rest of the Best Practices series you agree that we may as well include the reports in the big “PTE”.

Also, if you use ForNAV, 99.5% of all report changes can be done WITHOUT per tenant extensions so it becomes a non-issue all together.

Organizing the Per Tenant Extension

That is a story for another day, most likely wednesday or thursday as tomorrow I have other plans.

What do you think? Please leave your comments below.



Why best practices for Per Tenant Extensions?

About a month or so ago I did (or try to do) a webinar about best practices for Per Tenant Extensions. I was unhappy about the result but I guess the story should be told and I did promise to get back to you and finish it.

Well, I did and I am getting ready to start sharing what I think a “perfect” per-tenant extension should look like and as always I am looking for feedback and some interactive discussion.

Why just Per Tenant Extensions?

I believe we lost track of what we are good at as a community. I mean that in several ways but for this blog I will stick to Per Tenant Extensions.

Since we got AppSource a few years ago our community started partying away on it. This resulted in a whopping 1.800 apps for Business Central today.

Don’t get me wrong, I love AppSource and just like you I am proud of my contributions. However I do believe 1.800 apps is a bit much for our community.

This is most easily explained with an example.


Continue reading “Why best practices for Per Tenant Extensions?”

Making a Business Central upgrade (so much) easier…

Since the beginning of the year I have a new job/project for a partner in Denmark that you may never have heard of.

The reason for saying that is because they are (super) vertical and they don’t ever “sell against” other partners. The only competition is outside of the Business Central comminity.

What makes that cool is that I can essentially share anything I learn with you without feeling guilty I give away “IP” to competition. The better Business Central as a product is doing the better we can compete with other branche specific solutions. Win-win.

The Upgrade problem

One of the things I spent most of the september month on was to find and document a way to make upgrades from NAV to Business Central easier.

The good news is that we found a way to make upgrades up to 80% cheaper and to almost completely eliminate the dependency on highly skilled developers which in our ecosystem is the resource type that is the most difficult to find.

The Trick?

As part of the upgrade toolkit that Microsoft provides for Business Central is a piece that was designed for Great Plains (GP) customers migrating. This is called Table Mapping.

If you customize GP, a lot happens on SQL level, much more than in NAV where there is more meta data.

In order to be able to migrate custom GP tables to an extension to you lift a SQL Table to an extension without making it into an extension on premises.

How do I learn more?

Almost all of the content I created is un-gated and publically available. There is a blog, a github repository and a video.

Oh, and before I forget, there are several countries for which we look for partners to invest in our vertical solution.

Here are the links, and enjoy!

With love,