Generic Validator Method Pattern

Generic Validator Method Pattern is a design pattern which is an extension of Generic Method Pattern. Purpose of this design pattern is to validate one or more entities in a specific context. This is a very commonly used pattern in other languages, just that it is adjusted to Generic Method Pattern.


Generic Method Pattern

It has a public method and two business events which can be subscribed to change or extend the behaviour of the method.


Public Method may contain the following sequence of calls:

  1. UI Confirmation (Optional)

  2. OnBefore Business Event

  3. Execute Logic

  4. OnAfter Business Event

  5. UI Acknowledgement (Optional)

Generic Method Pattern better explained in "Design patterns for developing repeatable IP for Dynamics 365 Business Central"


Generic Validator Method Pattern

It has two public methods and two business events which can be subscribed to change or extend the behaviour of the method.


This pattern contains HasErrors and Validate public functions.


HasErrors Method

This method will check validation errors in the entity and stores errors in Errors parameter and returns true if there are any validation errors.


This method should contain the following sequence of calls:

  1. OnBefore Business Event

  2. Execute Logic

  3. OnAfter Business Event

Validate Method

This method will throw a multi line error message with all validation errors found in HasErrors method.


Sample Code

codeunit 50101 CreateSalesOrderValidator

{

    procedure Validate(Customer: Record Customer)

    var

        Errors: List of [Text];

    begin

        if HasErrors(Customer, Errors) then

            Error(ErrorsToText(Errors));

    end;



    procedure HasErrors(Customer: Record Customer; Errors: List of [Text]): Boolean

    var

        Handled: Boolean;

    begin

        OnBeforeCreateSalesOrderValidator(Customer, Handled);

        DoCreateSalesOrder(Customer, Errors, Handled);

        OnAfterCreateSalesOrderValidator(Customer);



        if Errors.Count() > 0 then

            exit(true);

    end;



    local procedure ErrorsToText(Errors: List of [Text]): Text

    var

        ErrText: Text;

        TxtBuffer: TextBuilder;

    begin

        foreach ErrText in Errors do

            TxtBuffer.AppendLine(ErrText);



        exit(TxtBuffer.ToText());

    end;



    local procedure DoCreateSalesOrder(Customer: Record Customer; Errors: List of [Text]; Handled: Boolean)

    begin

        if Handled then

            exit;



        ValidateGenBusinessPostingGroup(Customer, Errors);

        ValidateVATBusPostingGroup(Customer, Errors);

        ValidateVATRegistrationNo(Customer, Errors);

    end;



    local procedure ValidateGenBusinessPostingGroup(Customer: Record Customer; Errors: List of [Text])

    var

        GenBusPostingGroupErr: Label 'Gen. Bus. Posting Group should not be empty.';

    begin

        if Customer."Gen. Bus. Posting Group" = '' then

            Errors.Add(GenBusPostingGroupErr);

    end;



    local procedure ValidateVATBusPostingGroup(Customer: Record Customer; Errors: List of [Text])

    var

        GenBusPostingGroupErr: Label 'VAT Bus. Posting Group should not be empty.';

    begin

        if Customer."VAT Bus. Posting Group" = '' then

            Errors.Add(GenBusPostingGroupErr);

    end;



    local procedure ValidateVATRegistrationNo(Customer: Record Customer; Errors: List of [Text])

    var

        GenBusPostingGroupErr: Label 'Customer should have a valid VAT Registration No.';

    begin

        if Customer."VAT Registration No." = '' then

            Errors.Add(GenBusPostingGroupErr);

    end;



    [BusinessEvent(false)]

    local procedure OnBeforeCreateSalesOrderValidator(Customer: Record Customer; var Handled: Boolean)

    begin

    end;



    [BusinessEvent(false)]

    local procedure OnAfterCreateSalesOrderValidator(Customer: Record Customer)

    begin

    end;

}

Use Cases

This pattern can be used in the following senarios:

  • Postings, Actions

Validate Transactional Entities before posting or before performaning an action.

  • APIs, Web Services

Validating Entities before importing or accepting data via APIs or Web Services.


#MSDyn365 #MSDyn365BC #BusinessCentral #DynamicsNAV #DesignPatterns