Microsoft Dynamics NAV is soon to grow a generation older, when version 2009 is finally released. I already wrote about this version, and how it will come with all-new user interface, referred to as RoleTailored client. The best way to describe the changes in the interface in everyday terms, is that it is going through liposuction. The fat client we were so used to use is getting thinner. Not as thin as it gets, certainly not anorexic, but thin enough to introduce certain significant changes.
The biggest change is that, for the first time ever, the new client is not going to be an exclusive Microsoft Dynamics NAV client. The customers will be able to use the client both as a C/SIDE (good old fat) client, and new RoleTailored client. The and in the previous sentence is not really an and, and there is a big opportunity to really misunderstand the plans and strategy, and a huge opportunity (or better threat) to totally mess up the system during a 2009 roll-out. Let me explain.
New RoleTailored client is a three tier client, separating data, business logic and user interface from one another. The middle tier is used by RoleTailored client and is used to run business logic (application code), in the same way that current C/SIDE fat client does. Since the application objects themselves are stored in the database layer, the same codebase will be available both to C/SIDE and RoleTailored clients, thus enabling both of them to run simultaneously on the same network. However…
The RoleTailored client is not exactly the same kind of animal as C/SIDE client. Version 2009 will bring yet another object type: Page, which is used by the RoleTailored client much the same way the Form object is used in C/SIDE client. C/SIDE client can run forms, and cannot run pages, while RoleTailored client can run pages, and cannot run forms. Big deal, you might say. Yes, indeed it is. Because page object brings along lots of dogs to beware of. Let’s get to know few of them.
RoleTailored client is agnostic of form objects, while at the same time C/SIDE client is agnostic of page object. Both objects are referred to as FORM in C/AL code, and there is a strong rationale behind this: portability. To achieve the same functionality from user perspective, and keeping programmatical distinction between forms and pages, the C/AL code in the back would have to be completely rewritten, because the code would need to always be completely aware of the client type, and then run forms or pages, depending on whether the code is called from C/SIDE or RoleTailored client. When both objects are referred to simply as FORM, you don’t need to take care in the code which object will ultimately be shown to the end user, because the system takes care of this. Nice thingo, but this also means that there has to be functional match between forms and pages with regard to the object ID, or else you are toast. When the system would have to show Customer List in the C/SIDE client, therefore running the form 22, you better make sure that page 22 also represents customer list, otherwise your UI is inconsistent at best.
This one is a no brainer, really, and nice thing is that nice Microsoft Dynamics NAV development guys out there, wherever they be, are going to make sure that such a match exists between the forms and pages for standard forms. You are, however, the one who will need to take care of your own forms. For all of these forms a matching page object should be created, and woe unto ye who dare disobey.
But the real devil hides in the code. Although in the first place it was expected to have pages almost completely stripped off of code, this was just a dream. Pages are full of triggers almost completely matching the form triggers, which makes it possible to have completely different business logic behind forms and pages. Nothing can make you have the same piece of code execute on, say, Sell-to Customer No. field validation on the Sales Order form and Sales Order page. This can unleash such a hell, which Dante himself couldn’t have seen in his worst nightmares. Why do I say so? Because out in the wild, there are gazillions of tons of customizations relying heavily on form triggers, and to make for a consistent system, all of them have to be copied to the page triggers as well. A new sort of fun altogether.
But there is another one. Forms and pages may have completely different set of functions. Say you add a new global function SetDefaults to Customer Card form object, which does something important to the form prior to showing it to the user. Then you have a codeunit which does this:
If you don’t add the same function to the Customer Card page object, and you call this codeunit in the RoleTailored client, what do you think would happen? I’d expect an error to be thrown, but it won’t. The system, a tough guy, won’t say a word, he can handle it allright. It will just skip over the CustomerCard.SetDefaults call and proceed happily to the CustomerCard.RUN as if nothing happened. Eek!
So, what can you now do to get ready for the new version? Well, you could do a thing or two.
Create a new codeunit to keep all of your form business logic. Name it something like FormTriggers.
Move all of business logic from form triggers to FormTriggers codeunit. If you have code in, say, OnAfterGetRecord trigger in Customer Card form, move it to this codeunit under new function named CustomerCard_OnAfterGetRecord. Then from OnAfterGetRecord trigger in Customer Card form call FormTriggers.CustomerCard_OnAfterGetRecord.
If the form has some context (variables and such) which is accessed within OnAfterGetRecord, pass that context to the CustomerCard_OnAfterGetRecord as parameters. If this context is also modified, pass it by reference (Var).
Writing good and maintainable code was difficult in previous versions, but it wasn’t too easy to mess the things up completely. Now version 2009 is taking it to the new level altogether. Although the standard functionality will work equally well in both clients, and although it is true that developers need to be responsible for writing good code, the new architecture makes it so easy to introduce inconsistency. Personally, the sheer prospect of a possibility to have a slightest inconsistency in business logic between the clients, scares the hell out of me. Developers will need to be extra careful, and quality assurance will need to exert even more scrutiny over the code and how it is written and maintained.
So, start preparing for new system today, it’ll really be a great one! You just need to take care not to mess up something, somewhere…