What is Hooks
Pattern?
When doing development over years, by different
developers with different mind-sets, the standard code base gets changed a lot,
adding multiple lines of code, adding local and global variants, adding or
changing keys, changing existing business logic. In other terms,
the standard text objects are being changed all over the place.
After years, it's not clear why a change was done,
and what was the place where the change was intended to be done. And the
latter is quite important in an upgrade process, when code in the base product
is being refactored: if the exact place of the posting of the Customer Entry is
being redesigned to a separate number, the first thing I need to know, is that
I did a certain change at the place: "where the posting of the Customer
Entry starts". The definition of that place, we call a "Hook"
Hooks Pattern follows the
below process
First of all, name
the places in the already existing code where customization is needed, All
objects of the default applications that need to be changed
·
Second, place your business logic completely outside the already
existing application code.
On
objects that should not hold any customized business logic (like tables, pages,
XMLPorts)
Process:
Step1 - create your
Hook code unit. This is always a code unit. We apply the following
rules to it:
- One
Hook always hooks into one object. Which basically means that I will
only declare this new code unit in one other object (which is its parent
object)
- The
naming convention is: The_Original_Object_Name Hook.
Naming conventions are important, just to find your mapped object, and
also to be able to group the Hooks.
Step2- you create
the hook, which is basically a method (function) in your hook code unit.
The naming is important:
- The
naming of the hook should NOT describe what it is going to do (So,
examples like CheckMandatoryFields, FillCustomFields should
not be used as a hook)
- The
naming of the hook should describe WHERE the hook is placed, not what the
hook will be doing (as nobody is able to look into the future
- To
help with the naming, it is a good convention to use the
"On"-prefix for these triggers. This way, it's very clear
what are hooks, and what aren't.
Step 3- it's time to hook
it to its corresponding object and right place in the business logic of that
object. You do this by declaring your code unit as a global in your
object, and using the created hook function on its place in the business
logic. This way, these one-liners apply:
- A
Hook code unit is only used once in one object only (its corresponding
object)
- A
Hook (function) is used only once in that object. As a consequence,
changing the parameters has no consequence: you only need to change one
function-call
- The code
unit is declared as a global. That exact global is the only custom declarations
in the existing object. Everything else is pushed to the hook-code unit.
Step 4- implements your
business logic in the hook. Do this in the most atomic way, as there is a
good chance that this same hook is going to be used for other business logic as
well. Best is to use a one-line-function-call to business logic, so that
the Hook Function itself stays readable.
Example
Suppose,
we want to add business logic just before posting a sales document. In
that case, we have to look for the most relevant place, which is somewhere in
the "Sales-Post" codeunit. So:
Step
1: create code unit Sales-Post Hook:

Step 3: declare a global in the "Sales-Post"-codeunit, called
"SalesPostHook". Then, call the Hook Function that you created
in Step 2 in the right place.
Step 4: implement the business logic, by calling out to a new
function. And implement the test-code unit.
Pros:
·
It will make the upgrade process much easier.
·
It will be very readable what is being
customized on a certain place in an existing part of the application.
·
It is specially help full in handling large
customization.
·
It easy, elegant, and very manageable.
·
Some time we can re-use the code.
Cons:
·
We have to keep Standard function and hook
functions in sync always.
·
It is
mostly not useable, when most changes happen in the more places in one object.
·
Making
tricks and putting code in different places is making code hard to read and
un-necessary complex.
·
It may
increase the add-on cost because of extra objects and extra time(Assumption)
·
We can’t
use in-built functions in Hook code units like currPage.xxx,
·
Test the whole
functionality.
·
More investment
and less benefit, because Microsoft already released merge tool from NAV2015,
it saves our merging time.
Risks:
·
Time factor, only the add-on is already developed without hook
·
Cost, it needs to more time for refactoring the whole logic.
·
Hook code unit naming conventions might collide when the application is
using more than one add-on from different partners. Suppose three different partners
are using the same hook name like sales post-hook with three different ID,
system doesn’t allow while importing the objects.
·
Hook functions naming conventions is always as challenge. It must be
easily understandable when we have multiple hooks in the same trigger.
·
It is always complex while merging\upgrading objects when the source
version doesn’t have the hook pattern and destination version has, in case of
customer has more add-ons from different partners.
·
Current record fields return variable and global variable handling is
very complex.
No comments:
Post a Comment