573 lines
No EOL
67 KiB
HTML
573 lines
No EOL
67 KiB
HTML
<!doctype html><html lang=en class="js csstransforms3d">
|
|
<head>
|
|
<meta charset=utf-8>
|
|
<meta name=viewport content="width=device-width,initial-scale=1">
|
|
<meta name=generator content="Hugo 0.92.2">
|
|
<meta name=description content>
|
|
<title>Generic Method Pattern :: AL Guidelines</title>
|
|
<link href=/css/nucleus.css?1644959101 rel=stylesheet>
|
|
<link href=/css/fontawesome-all.min.css?1644959101 rel=stylesheet>
|
|
<link href=/css/featherlight.min.css?1644959101 rel=stylesheet>
|
|
<link href=/css/perfect-scrollbar.min.css?1644959101 rel=stylesheet>
|
|
<link href=/css/auto-complete.css?1644959101 rel=stylesheet>
|
|
<link href=/css/theme.css?1644959101 rel=stylesheet>
|
|
<link href=/css/theme-blue.css?1644959101 rel=stylesheet>
|
|
<link href=/css/variant.css?1644959101 rel=stylesheet>
|
|
<link href=/css/print.css?1644959101 rel=stylesheet media=print>
|
|
<script src=/js/jquery.min.js?1644959101></script>
|
|
<style>:root #header+#content>#left>#rlblock_left{display:none!important}</style>
|
|
</head>
|
|
<body data-url=/bcpatterns/generic-method-pattern/>
|
|
<script>var index_url="/index.json",root_url="/",baseUri=root_url.replace(/\/$/,'')</script>
|
|
<nav id=sidebar>
|
|
<div id=header-wrapper>
|
|
<div id=header>
|
|
<a id=logo href=/ style="color:#f5f5f5;font-family:segoe ui semibold,segoe ui,SegoeUI,helvetica neue,Helvetica,Arial,sans-serif;font-size:30px;font-weight:300;margin-top:-2px">
|
|
ALGuidelines.Dev
|
|
</a>
|
|
<i style=color:#f5f5f5>Code is Poetry ...</i>
|
|
</div>
|
|
<div class=searchbox>
|
|
<label for=search-by><i class="fas fa-search"></i></label>
|
|
<input data-search-input id=search-by type=search placeholder=Search...>
|
|
<span data-search-clear><i class="fas fa-times"></i></span>
|
|
</div>
|
|
<script src=/js/lunr.min.js?1644959101></script>
|
|
<script src=/js/auto-complete.js?1644959101></script>
|
|
<script src=/js/search.js?1644959101></script>
|
|
</div>
|
|
<div class=highlightable>
|
|
<ul class=topics>
|
|
<li data-nav-id=/welcome/ title=Welcome class=dd-item><a href=/welcome/><b><i class="fas fa-home"></i> </b>Welcome</a><ul></ul></li>
|
|
<li data-nav-id=/bcpatterns/ title="BC Patterns" class="dd-item parent"><a href=/bcpatterns/><b><i class="fas fa-clone"></i> </b>BC Patterns</a><ul>
|
|
<li data-nav-id=/bcpatterns/facade-pattern/ title="Facade Pattern" class=dd-item><a href=/bcpatterns/facade-pattern/>Facade Pattern</a></li>
|
|
<li data-nav-id=/bcpatterns/generic-method-pattern/ title="Generic Method Pattern" class="dd-item active"><a href=/bcpatterns/generic-method-pattern/>Generic Method Pattern</a></li></ul></li>
|
|
<li data-nav-id=/bcbestpractices/ title="BC Dev. Best Practices" class=dd-item><a href=/bcbestpractices/><b><i class="fas fa-medal"></i> </b>BC Dev. Best Practices</a><ul>
|
|
<li data-nav-id=/bcbestpractices/performance/ title=Performance class=dd-item><a href=/bcbestpractices/performance/>Performance</a><ul>
|
|
<li data-nav-id=/bcbestpractices/performance/subscribercodeunits/ title="Subscriber Codeunits" class=dd-item><a href=/bcbestpractices/performance/subscribercodeunits/>Subscriber Codeunits</a></li></ul></li>
|
|
<li data-nav-id=/bcbestpractices/readability/ title=Readability class=dd-item><a href=/bcbestpractices/readability/>Readability</a><ul>
|
|
<li data-nav-id=/bcbestpractices/readability/begin-as-an-afterword/ title="begin as an 'After Word'" class=dd-item><a href=/bcbestpractices/readability/begin-as-an-afterword/>begin as an 'After Word'</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/begin-end/ title="Begin-End - Compound Only" class=dd-item><a href=/bcbestpractices/readability/begin-end/>Begin-End - Compound Only</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/binary-operator-line-start/ title="Binary Operator to Start Line" class=dd-item><a href=/bcbestpractices/readability/binary-operator-line-start/>Binary Operator to Start Line</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/case-actions/ title="CASE Action on next line" class=dd-item><a href=/bcbestpractices/readability/case-actions/>CASE Action on next line</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/comments-spacing/ title="Comment Spacing" class=dd-item><a href=/bcbestpractices/readability/comments-spacing/>Comment Spacing</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/end-else-pair/ title="end else pair" class=dd-item><a href=/bcbestpractices/readability/end-else-pair/>end else pair</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/keyword-pairs-indentation/ title="Keyword Pairs - Indentation" class=dd-item><a href=/bcbestpractices/readability/keyword-pairs-indentation/>Keyword Pairs - Indentation</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/line-start-keywords/ title="Line Start Keywords" class=dd-item><a href=/bcbestpractices/readability/line-start-keywords/>Line Start Keywords</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/lonely-repeat/ title="Lonely Repeat" class=dd-item><a href=/bcbestpractices/readability/lonely-repeat/>Lonely Repeat</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/named-invocations/ title="Named Invocations" class=dd-item><a href=/bcbestpractices/readability/named-invocations/>Named Invocations</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/one-statement-per-line/ title="One Statement Per Line" class=dd-item><a href=/bcbestpractices/readability/one-statement-per-line/>One Statement Per Line</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/separate-if-and-else/ title="Separate if and else" class=dd-item><a href=/bcbestpractices/readability/separate-if-and-else/>Separate if and else</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/spacing-binary-operators/ title="Spacing Binary Operators" class=dd-item><a href=/bcbestpractices/readability/spacing-binary-operators/>Spacing Binary Operators</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/suggested-abbreviations/ title="Suggested Abbreviations" class=dd-item><a href=/bcbestpractices/readability/suggested-abbreviations/>Suggested Abbreviations</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/unnecessary-else/ title="Unnecessary 'else'" class=dd-item><a href=/bcbestpractices/readability/unnecessary-else/>Unnecessary 'else'</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/unnecessary-truefalse/ title="Unnecessary true/false" class=dd-item><a href=/bcbestpractices/readability/unnecessary-truefalse/>Unnecessary true/false</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/variable-naming/ title="Variable Naming" class=dd-item><a href=/bcbestpractices/readability/variable-naming/>Variable Naming</a></li>
|
|
<li data-nav-id=/bcbestpractices/readability/variables-declarations-order/ title="Variables Declarations Order" class=dd-item><a href=/bcbestpractices/readability/variables-declarations-order/>Variables Declarations Order</a></li></ul></li></ul></li>
|
|
<li data-nav-id=/navpatterns/ title="NAV Patterns Archive" class=dd-item><a href=/navpatterns/><b><i class="fas fa-save"></i> </b>NAV Patterns Archive</a><ul>
|
|
<li data-nav-id=/navpatterns/1-patterns/ title="1. Patterns" class=dd-item><a href=/navpatterns/1-patterns/>1. Patterns</a><ul>
|
|
<li data-nav-id=/navpatterns/1-patterns/activity-log/ title="Activity Logs" class=dd-item><a href=/navpatterns/1-patterns/activity-log/>Activity Logs</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/argument-table/ title="Argument Table" class=dd-item><a href=/navpatterns/1-patterns/argument-table/>Argument Table</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/blocked-entity/ title="Blocked Entity" class=dd-item><a href=/navpatterns/1-patterns/blocked-entity/>Blocked Entity</a><ul>
|
|
<li data-nav-id=/navpatterns/1-patterns/blocked-entity/data-driven-blocked-entity/ title="Data Driven Blocked Entity" class=dd-item><a href=/navpatterns/1-patterns/blocked-entity/data-driven-blocked-entity/>Data Driven Blocked Entity</a></li></ul></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/cached-web-service-calls/ title="Cached Web Server Calls" class=dd-item><a href=/navpatterns/1-patterns/cached-web-service-calls/>Cached Web Server Calls</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/conditional-cascading-update/ title="Conditional Cascading Update" class=dd-item><a href=/navpatterns/1-patterns/conditional-cascading-update/>Conditional Cascading Update</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/copy-document/ title="Copy Document" class=dd-item><a href=/navpatterns/1-patterns/copy-document/>Copy Document</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/create-data-from-templates/ title="Create Data from Templates" class=dd-item><a href=/navpatterns/1-patterns/create-data-from-templates/>Create Data from Templates</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/create-urls-to-nav-clients/ title="Create URLs to NAV Clients" class=dd-item><a href=/navpatterns/1-patterns/create-urls-to-nav-clients/>Create URLs to NAV Clients</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/creating-custom-charts/ title="Creating Custom Charts" class=dd-item><a href=/navpatterns/1-patterns/creating-custom-charts/>Creating Custom Charts</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/cross-session-events/ title="Cross Session Events" class=dd-item><a href=/navpatterns/1-patterns/cross-session-events/>Cross Session Events</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/currently-active-record/ title="Currently Active Record" class=dd-item><a href=/navpatterns/1-patterns/currently-active-record/>Currently Active Record</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/data-migration-facade/ title="Data Migration Façade" class=dd-item><a href=/navpatterns/1-patterns/data-migration-facade/>Data Migration Façade</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/discovery-event/ title="Discovery Event" class=dd-item><a href=/navpatterns/1-patterns/discovery-event/>Discovery Event</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/document/ title=Document class=dd-item><a href=/navpatterns/1-patterns/document/>Document</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/easy-update-of-setup-or-supplementary-information/ title="Easy Update Of Setup Or Supplementary Information" class=dd-item><a href=/navpatterns/1-patterns/easy-update-of-setup-or-supplementary-information/>Easy Update Of Setup Or Supplementary Information</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/error-message-processing/ title="Error Message Processing" class=dd-item><a href=/navpatterns/1-patterns/error-message-processing/>Error Message Processing</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/extending-the-role-center-headlines/ title="Extending the Role Center Headlines" class=dd-item><a href=/navpatterns/1-patterns/extending-the-role-center-headlines/>Extending the Role Center Headlines</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/feature-localization-for-data-structures/ title="Feature Localization For Data Structures" class=dd-item><a href=/navpatterns/1-patterns/feature-localization-for-data-structures/>Feature Localization For Data Structures</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/hooks/ title=Hooks class=dd-item><a href=/navpatterns/1-patterns/hooks/>Hooks</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/implementation-of-surrogate-keys-using-autoincrement-pattern/ title="Surrogate keys using Autoincrement Pattern" class=dd-item><a href=/navpatterns/1-patterns/implementation-of-surrogate-keys-using-autoincrement-pattern/>Surrogate keys using Autoincrement Pattern</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/instructions-in-the-ui/ title="Instructions in the UI" class=dd-item><a href=/navpatterns/1-patterns/instructions-in-the-ui/>Instructions in the UI</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/integration-of-addresses/ title="Integration of Addresses" class=dd-item><a href=/navpatterns/1-patterns/integration-of-addresses/>Integration of Addresses</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/journal-error-processing/ title="Journal Error Processing" class=dd-item><a href=/navpatterns/1-patterns/journal-error-processing/>Journal Error Processing</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/journal-template-batch-line/ title="Journal Template Batch Line" class=dd-item><a href=/navpatterns/1-patterns/journal-template-batch-line/>Journal Template Batch Line</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/master-data/ title="Master Data" class=dd-item><a href=/navpatterns/1-patterns/master-data/>Master Data</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/multi-file-download/ title="Multi-file Download" class=dd-item><a href=/navpatterns/1-patterns/multi-file-download/>Multi-file Download</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/multi-page-list/ title="Multi-Page List" class=dd-item><a href=/navpatterns/1-patterns/multi-page-list/>Multi-Page List</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/multilanguage-application-data/ title="Multilanguage Application Data" class=dd-item><a href=/navpatterns/1-patterns/multilanguage-application-data/>Multilanguage Application Data</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/net-exception-handling-in-cal/ title="NET Exception Handling in CAL" class=dd-item><a href=/navpatterns/1-patterns/net-exception-handling-in-cal/>NET Exception Handling in CAL</a><ul>
|
|
<li data-nav-id=/navpatterns/1-patterns/net-exception-handling-in-cal/tryfunction-net-exception-handling-in-cal/ title="TryFunction NET Exception Handling in CAL" class=dd-item><a href=/navpatterns/1-patterns/net-exception-handling-in-cal/tryfunction-net-exception-handling-in-cal/>TryFunction NET Exception Handling in CAL</a></li></ul></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/no-series/ title="No Series" class=dd-item><a href=/navpatterns/1-patterns/no-series/>No Series</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/notifications/ title=Notifications class=dd-item><a href=/navpatterns/1-patterns/notifications/>Notifications</a><ul>
|
|
<li data-nav-id=/navpatterns/1-patterns/notifications/in-context-notifications/ title="In-context Notifications" class=dd-item><a href=/navpatterns/1-patterns/notifications/in-context-notifications/>In-context Notifications</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/notifications/notification-lifecycle-management-pattern/ title="Notification Lifecycle Management Pattern" class=dd-item><a href=/navpatterns/1-patterns/notifications/notification-lifecycle-management-pattern/>Notification Lifecycle Management Pattern</a></li></ul></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/observer/ title=Observer class=dd-item><a href=/navpatterns/1-patterns/observer/>Observer</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/posting-routine-select-behavior/ title="Posting Routine - Select Behavior" class=dd-item><a href=/navpatterns/1-patterns/posting-routine-select-behavior/>Posting Routine - Select Behavior</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/product-name/ title="Product Name" class=dd-item><a href=/navpatterns/1-patterns/product-name/>Product Name</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/queries/ title=Queries class=dd-item><a href=/navpatterns/1-patterns/queries/>Queries</a><ul>
|
|
<li data-nav-id=/navpatterns/1-patterns/queries/select-distinct-with-queries/ title="SELECT DISTINCT with Queries" class=dd-item><a href=/navpatterns/1-patterns/queries/select-distinct-with-queries/>SELECT DISTINCT with Queries</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/queries/use-queries-to-detect-duplicate-records/ title="Use Queries to Detect Duplicate Records" class=dd-item><a href=/navpatterns/1-patterns/queries/use-queries-to-detect-duplicate-records/>Use Queries to Detect Duplicate Records</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/queries/use-queries-to-replace-nested-loops/ title="Use Queries to Replace Nested Loops" class=dd-item><a href=/navpatterns/1-patterns/queries/use-queries-to-replace-nested-loops/>Use Queries to Replace Nested Loops</a></li></ul></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/read-once-initialization-and-validation/ title="Read-once Initialization and Validation" class=dd-item><a href=/navpatterns/1-patterns/read-once-initialization-and-validation/>Read-once Initialization and Validation</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/released-entity/ title="Released Entity" class=dd-item><a href=/navpatterns/1-patterns/released-entity/>Released Entity</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/report-selection/ title="Report Selection" class=dd-item><a href=/navpatterns/1-patterns/report-selection/>Report Selection</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/security/ title=Security class=dd-item><a href=/navpatterns/1-patterns/security/>Security</a><ul>
|
|
<li data-nav-id=/navpatterns/1-patterns/security/1-sensitive-data-encapsulation/ title="Sensitive Data Encapsulation" class=dd-item><a href=/navpatterns/1-patterns/security/1-sensitive-data-encapsulation/>Sensitive Data Encapsulation</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/security/2-data-encryption/ title="Data Encryption" class=dd-item><a href=/navpatterns/1-patterns/security/2-data-encryption/>Data Encryption</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/security/3-single-point-of-access/ title="Single Point of Access" class=dd-item><a href=/navpatterns/1-patterns/security/3-single-point-of-access/>Single Point of Access</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/security/4-masked-text/ title="Masked Text" class=dd-item><a href=/navpatterns/1-patterns/security/4-masked-text/>Masked Text</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/security/5-ssl-in-nav/ title="SSL in NAV" class=dd-item><a href=/navpatterns/1-patterns/security/5-ssl-in-nav/>SSL in NAV</a></li></ul></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/setup-specificity-fallback/ title="Setup Specificity Fallback" class=dd-item><a href=/navpatterns/1-patterns/setup-specificity-fallback/>Setup Specificity Fallback</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/silent-file-upload-and-download/ title="Silent File Upload and Download" class=dd-item><a href=/navpatterns/1-patterns/silent-file-upload-and-download/>Silent File Upload and Download</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/singleton/ title=Singleton class=dd-item><a href=/navpatterns/1-patterns/singleton/>Singleton</a><ul>
|
|
<li data-nav-id=/navpatterns/1-patterns/singleton/singleton-codeunit/ title="Singleton Codeunit" class=dd-item><a href=/navpatterns/1-patterns/singleton/singleton-codeunit/>Singleton Codeunit</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/singleton/singleton-table/ title="Singleton Table" class=dd-item><a href=/navpatterns/1-patterns/singleton/singleton-table/>Singleton Table</a><ul>
|
|
<li data-nav-id=/navpatterns/1-patterns/singleton/singleton-table/cue-table/ title="Cue Table" class=dd-item><a href=/navpatterns/1-patterns/singleton/singleton-table/cue-table/>Cue Table</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/singleton/singleton-table/setup-table/ title="Setup Table" class=dd-item><a href=/navpatterns/1-patterns/singleton/singleton-table/setup-table/>Setup Table</a></li></ul></li></ul></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/standard-journal/ title="Standard Journal" class=dd-item><a href=/navpatterns/1-patterns/standard-journal/>Standard Journal</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/temporary-dataset-report/ title="Temporary Dataset Report" class=dd-item><a href=/navpatterns/1-patterns/temporary-dataset-report/>Temporary Dataset Report</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/totals-and-discounts-on-subpages-sales-and-purchases/ title="Totals and Discounts on Subpages Sales and Purchases" class=dd-item><a href=/navpatterns/1-patterns/totals-and-discounts-on-subpages-sales-and-purchases/>Totals and Discounts on Subpages Sales and Purchases</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/transfer-custom-fields/ title="Transfer Custom Fields" class=dd-item><a href=/navpatterns/1-patterns/transfer-custom-fields/>Transfer Custom Fields</a></li>
|
|
<li data-nav-id=/navpatterns/1-patterns/variant-facade/ title="Variant Facade" class=dd-item><a href=/navpatterns/1-patterns/variant-facade/>Variant Facade</a></li></ul></li>
|
|
<li data-nav-id=/navpatterns/2-anti-patterns/ title="2. Anti-Patterns" class=dd-item><a href=/navpatterns/2-anti-patterns/>2. Anti-Patterns</a><ul>
|
|
<li data-nav-id=/navpatterns/2-anti-patterns/nav-upgrade/ title="Nav Upgrade" class=dd-item><a href=/navpatterns/2-anti-patterns/nav-upgrade/>Nav Upgrade</a></li>
|
|
<li data-nav-id=/navpatterns/2-anti-patterns/reusable-bugs/ title="Reusable Bugs" class=dd-item><a href=/navpatterns/2-anti-patterns/reusable-bugs/>Reusable Bugs</a></li></ul></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/ title="3. CAL Coding Guidelines" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/>3. CAL Coding Guidelines</a><ul>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/ title=Design class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/>Design</a><ul>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/by-reference-parameters/ title="By Reference Parameters" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/by-reference-parameters/>By Reference Parameters</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/class-coupling/ title="Class Coupling" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/class-coupling/>Class Coupling</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/cyclomatic-complexity/ title="Cyclomatic Complexity" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/cyclomatic-complexity/>Cyclomatic Complexity</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/encapsulate-local-functionality/ title="Encapsulate Local Functionality" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/encapsulate-local-functionality/>Encapsulate Local Functionality</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/findset-findfirst-findlast/ title="FINDSET FINDFIRST FINDLAST" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/findset-findfirst-findlast/>FINDSET FINDFIRST FINDLAST</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/initialized-variables/ title="Initialized Variables" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/initialized-variables/>Initialized Variables</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/maintainability-index/ title="Maintainability Index" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/maintainability-index/>Maintainability Index</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/parameter-placeholders/ title="Parameter Placeholders" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/parameter-placeholders/>Parameter Placeholders</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/static-object-invocation/ title="Static Object Invocation" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/static-object-invocation/>Static Object Invocation</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/unreachable-code/ title="Unreachable Code" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/unreachable-code/>Unreachable Code</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/unused-initialized-variables/ title="Unused Initialized Variables" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/unused-initialized-variables/>Unused Initialized Variables</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/unused-variables/ title="Unused Variables" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/unused-variables/>Unused Variables</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/variable-capacity-mismatch/ title="Variable Capacity Mismatch" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/variable-capacity-mismatch/>Variable Capacity Mismatch</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/design/with-scope-name-collision/ title="WITH Scope Name Collision" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/design/with-scope-name-collision/>WITH Scope Name Collision</a></li></ul></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/internally-used-dot-net-types/ title="Internally used DotNet Types" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/internally-used-dot-net-types/>Internally used DotNet Types</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/internationalization/ title=Internationalization class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/internationalization/>Internationalization</a><ul>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/internationalization/using-calcdate/ title="Using Calcdate" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/internationalization/using-calcdate/>Using Calcdate</a></li></ul></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/localizability/ title=Localizability class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/localizability/>Localizability</a><ul>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/localizability/captionml-for-system-tables/ title="CaptionML on System Pages" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/localizability/captionml-for-system-tables/>CaptionML on System Pages</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/localizability/fieldcaption-and-tablecaption/ title="FIELDCAPTION and TABLECAPTION" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/localizability/fieldcaption-and-tablecaption/>FIELDCAPTION and TABLECAPTION</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/localizability/global-text-constants/ title="Global Text Constants" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/localizability/global-text-constants/>Global Text Constants</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/localizability/use-text-constants/ title="Use Text Constants" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/localizability/use-text-constants/>Use Text Constants</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/localizability/using-optioncaptionml/ title="Using OptionCaptionML" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/localizability/using-optioncaptionml/>Using OptionCaptionML</a></li></ul></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/ title=Readability class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/>Readability</a><ul>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/begin-as-an-afterword/ title="Begin as an 'After Word'" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/begin-as-an-afterword/>Begin as an 'After Word'</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/begin-end/ title="Begin-End - Compound Only" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/begin-end/>Begin-End - Compound Only</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/binary-operator-line-start/ title="Binary Operator to Start Line" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/binary-operator-line-start/>Binary Operator to Start Line</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/blank-lines/ title="Blank Lines" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/blank-lines/>Blank Lines</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/case-actions/ title="CASE Action" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/case-actions/>CASE Action</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/colon-usage-in-case/ title="Colon usage in CASE" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/colon-usage-in-case/>Colon usage in CASE</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/comments-curly-brackets/ title="Comments inside Curly Brackets" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/comments-curly-brackets/>Comments inside Curly Brackets</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/comments-spacing/ title="Comment Spacing" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/comments-spacing/>Comment Spacing</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/end-else-pair/ title="END ELSE Pair" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/end-else-pair/>END ELSE Pair</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/indentation/ title=Indentation class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/indentation/>Indentation</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/keyword-pairs-indentation/ title="Keyword Pairs - Indentation" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/keyword-pairs-indentation/>Keyword Pairs - Indentation</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/line-start-keywords/ title="Line Start Keywords" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/line-start-keywords/>Line Start Keywords</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/lonely-repeat/ title="Lonely Repeat" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/lonely-repeat/>Lonely Repeat</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/named-invocations/ title="Named Invocations" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/named-invocations/>Named Invocations</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/nested-withs/ title="Nested WITHs" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/nested-withs/>Nested WITHs</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/one-statement-per-line/ title="One Statement Per Line" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/one-statement-per-line/>One Statement Per Line</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/separate-if-and-else/ title="Separate IF and ELSE" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/separate-if-and-else/>Separate IF and ELSE</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/spacing-binary-operators/ title="Spacing Binary Operators" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/spacing-binary-operators/>Spacing Binary Operators</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/spacing-brackets-and/ title="Spacing Brackets and ::" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/spacing-brackets-and/>Spacing Brackets and ::</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/spacing-unary-operators/ title="Spacing Unary Operators" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/spacing-unary-operators/>Spacing Unary Operators</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/suggested-abbreviations/ title="Suggested Abbreviations" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/suggested-abbreviations/>Suggested Abbreviations</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/temporary-variable-naming/ title="Temporary Variable Naming" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/temporary-variable-naming/>Temporary Variable Naming</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/textconst-suffixes/ title="TextConst Suffixes" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/textconst-suffixes/>TextConst Suffixes</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/unary-operator-line-end/ title="Unary Operator Line End" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/unary-operator-line-end/>Unary Operator Line End</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/unnecessary-compound-parenthesis/ title="Unnecessary Compound Parenthesis" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/unnecessary-compound-parenthesis/>Unnecessary Compound Parenthesis</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/unnecessary-else/ title="Unnecessary ELSE" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/unnecessary-else/>Unnecessary ELSE</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/unnecessary-function-parenthesis/ title="Unnecessary Function Parenthesis" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/unnecessary-function-parenthesis/>Unnecessary Function Parenthesis</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/unnecessary-separators/ title="Unnecessary Separators" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/unnecessary-separators/>Unnecessary Separators</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/unnecessary-truefalse/ title="Unnecessary TRUE/FALSE" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/unnecessary-truefalse/>Unnecessary TRUE/FALSE</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/variable-already-scoped/ title="Variable Already Scoped" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/variable-already-scoped/>Variable Already Scoped</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/variable-naming/ title="Variable Naming" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/variable-naming/>Variable Naming</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/readability/variables-declarations-order/ title="Variables Declarations Order" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/readability/variables-declarations-order/>Variables Declarations Order</a></li></ul></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/ux/ title=UX class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/ux/>UX</a><ul>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/ux/actions-images/ title="Actions - Images" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/ux/actions-images/>Actions - Images</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/ux/confirm/ title=CONFIRM class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/ux/confirm/>CONFIRM</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/ux/fielderror/ title=FIELDERROR class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/ux/fielderror/>FIELDERROR</a></li>
|
|
<li data-nav-id=/navpatterns/3-cal-coding-guidelines/ux/message-and-error/ title="MESSAGE and ERROR" class=dd-item><a href=/navpatterns/3-cal-coding-guidelines/ux/message-and-error/>MESSAGE and ERROR</a></li></ul></li></ul></li>
|
|
<li data-nav-id=/navpatterns/4-get-involved/ title="(OLD) Get Involved" class=dd-item><a href=/navpatterns/4-get-involved/>(OLD) Get Involved</a><ul>
|
|
<li data-nav-id=/navpatterns/4-get-involved/code-of-conduct/ title="Code of Conduct" class=dd-item><a href=/navpatterns/4-get-involved/code-of-conduct/>Code of Conduct</a></li>
|
|
<li data-nav-id=/navpatterns/4-get-involved/patterns-authors/ title="Patterns Authors" class=dd-item><a href=/navpatterns/4-get-involved/patterns-authors/>Patterns Authors</a></li>
|
|
<li data-nav-id=/navpatterns/4-get-involved/template-for-writing-nav-design-patterns/ title="Template for writing Nav Design Patterns" class=dd-item><a href=/navpatterns/4-get-involved/template-for-writing-nav-design-patterns/>Template for writing Nav Design Patterns</a></li></ul></li>
|
|
<li data-nav-id=/navpatterns/related-links/ title="Related Links" class=dd-item><a href=/navpatterns/related-links/>Related Links</a></li></ul></li>
|
|
<li data-nav-id=/contributing/ title=Contributing class=dd-item><a href=/contributing/><b><i class="fas fa-clone"></i> </b>Contributing</a><ul>
|
|
<li data-nav-id=/contributing/formattingtips/ title="Formatting tips" class=dd-item><a href=/contributing/formattingtips/><b><i class="fas fa-clone"></i> </b>Formatting tips</a></li>
|
|
<li data-nav-id=/contributing/forkandpr/ title="Guide to Fork & PR" class=dd-item><a href=/contributing/forkandpr/><b><i class="fas fa-clone"></i> </b>Guide to Fork & PR</a></li>
|
|
<li data-nav-id=/contributing/templates/ title=Templates class=dd-item><a href=/contributing/templates/><b><i class="fas fa-clone"></i> </b>Templates</a><ul>
|
|
<li data-nav-id=/contributing/templates/guidelines/ title="Title of the Guideline" class=dd-item><a href=/contributing/templates/guidelines/>Title of the Guideline</a></li>
|
|
<li data-nav-id=/contributing/templates/patterns/ title="Title of the pattern" class=dd-item><a href=/contributing/templates/patterns/>Title of the pattern</a></li></ul></li>
|
|
<li data-nav-id=/contributing/theapprovalprocess/ title="Understanding the Approval Process" class=dd-item><a href=/contributing/theapprovalprocess/><b><i class="fas fa-clone"></i> </b>Understanding the Approval Process</a></li></ul></li>
|
|
<li data-nav-id=/discussions/ title=Discussions class=dd-item><a href=/discussions/><b><i class="fas fa-clone"></i> </b>Discussions</a><ul></ul></li>
|
|
</ul>
|
|
<div id=shortcuts>
|
|
<div class=nav-title>More</div>
|
|
<ul>
|
|
<li><a class=padding href=https://discord.gg/4wbfNv3><i class="fab fa-discord"></i> BC Discord</a></li>
|
|
<li><a class=padding href=https://github.com/microsoft/alguidelines><i class="fab fa-github"></i> GitHub repo</a></li>
|
|
</ul>
|
|
</div>
|
|
<div id=footer>
|
|
<p>Built with <a href=https://github.com/McShelby/hugo-theme-relearn><i class="fas fa-heart"></i></a> by <a href=https://gohugo.io/>Hugo</a></p>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
<div id=body>
|
|
<div id=overlay></div>
|
|
<div class="padding highlightable">
|
|
<div id=top-bar>
|
|
<div id=top-github-link>
|
|
<a class=github-link title="Edit this page" href=https://github.com/microsoft/alguidelines/edit/main/content/BCPatterns/generic-method-pattern/index.md target=blank>
|
|
<i class="fas fa-code-branch"></i>
|
|
<span id=top-github-link-text>Edit this page</span>
|
|
</a>
|
|
</div>
|
|
<div id=breadcrumbs>
|
|
<span id=sidebar-toggle-span>
|
|
<a href=# id=sidebar-toggle data-sidebar-toggle>
|
|
<i class="fas fa-bars"></i>
|
|
</a>
|
|
</span>
|
|
<span id=toc-menu><i class="fas fa-list-alt"></i></span>
|
|
<ol class=links itemscope itemtype=http://schema.org/BreadcrumbList>
|
|
<meta itemprop=itemListOrder content="Descending">
|
|
<li itemscope itemtype=https://schema.org/ListItem itemprop=itemListElement><meta itemprop=position content="3"><a itemprop=item href=/><span itemprop=name>Home</span></a> > </li>
|
|
<li itemscope itemtype=https://schema.org/ListItem itemprop=itemListElement><meta itemprop=position content="2"><a itemprop=item href=/bcpatterns/><span itemprop=name>BC Patterns</span></a> > </li>
|
|
<li itemscope itemtype=https://schema.org/ListItem itemprop=itemListElement><meta itemprop=position content="1"><a itemprop=item href=/bcpatterns/generic-method-pattern/ aria-disabled=true><span itemprop=name>Generic Method Pattern</span></a></li>
|
|
</ol>
|
|
</div>
|
|
<div class=progress>
|
|
<div class=wrapper>
|
|
<nav id=TableOfContents>
|
|
<ul>
|
|
<li><a href=#abstract>Abstract</a></li>
|
|
<li><a href=#context>Context</a></li>
|
|
<li><a href=#problem>Problem</a></li>
|
|
<li><a href=#description>Description</a>
|
|
<ul>
|
|
<li><a href=#what-is-a-method>What is a method?</a></li>
|
|
<li><a href=#the-pattern>The Pattern</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href=#usage>Usage</a></li>
|
|
<li><a href=#benefits>Benefits</a>
|
|
<ul>
|
|
<li><a href=#extensibility>Extensibility</a></li>
|
|
<li><a href=#decoupling>Decoupling</a></li>
|
|
<li><a href=#readability>Readability</a></li>
|
|
<li><a href=#testability>Testability</a></li>
|
|
<li><a href=#encapsulation>Encapsulation</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href=#when-not-to-use>When not to use</a></li>
|
|
<li><a href=#snippets>Snippets</a></li>
|
|
<li><a href=#list-of-references>List of references</a></li>
|
|
<li><a href=#discussions>Discussions</a></li>
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id=head-tags>
|
|
</div>
|
|
<main id=body-inner>
|
|
<h1>Generic Method Pattern</h1>
|
|
<p><em>Created by Gary Winter (Cloud Ready Software), Described by waldo (iFacto Business Solutions | Dynex)</em></p>
|
|
<h2 id=abstract>Abstract</h2>
|
|
<p>The goal of this pattern is to facilitate a lot of things in one single awesome way of writing code. If you apply this pattern as a general pattern, you’ll implement:</p>
|
|
<ul>
|
|
<li>Extensibility</li>
|
|
<li>Decoupling</li>
|
|
<li>Readability</li>
|
|
<li>Testability</li>
|
|
<li>Encapsulation</li>
|
|
</ul>
|
|
<h2 id=context>Context</h2>
|
|
<p>Whenever you have to write an isolated piece of business logic, this pattern should be applicable.</p>
|
|
<h2 id=problem>Problem</h2>
|
|
<p>Usually, when you ask people where to place code, they all have their own opinion: on a table or page, or in some kind of codeunit library where lots of functions will be placed, or .. . In fact, does it matter? It sure does, because in many cases, the code simply isn’t maintainable, let alone extendable or testable.</p>
|
|
<h2 id=description>Description</h2>
|
|
<p>What if we have some kind of “standard way” to always write our code. The <em>Generic Method Pattern</em> is kind of like what it says: a generic way to implement a method.</p>
|
|
<h3 id=what-is-a-method>What is a method?</h3>
|
|
<p>Well, a method is <em>a significant piece of business logic</em> - maybe best explained by some examples:</p>
|
|
<ul>
|
|
<li>Posting a document</li>
|
|
<li>Any button on a page that executes business logic</li>
|
|
<li>a batch run to send emails</li>
|
|
<li>…</li>
|
|
</ul>
|
|
<p>In a way, except “data validation”, most of the things we write in our daily life, are methods.</p>
|
|
<h3 id=the-pattern>The Pattern</h3>
|
|
<p><strong>One method, one codeunit</strong>
|
|
The idea is to put the code in one <em>encapsulated</em> codeunit with the purpose to have all the code in that one codeunit function for that one method. This way, the codeunit will stay relatively small and readable.</p>
|
|
<p>Let me start by showing an example, so you can refer to this complete example during the rest of the article:</p>
|
|
<div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-AL data-lang=AL><span style=color:#66d9ef>codeunit</span> <span style=color:#ae81ff>53100</span> "WLD BlockCustomer Meth"
|
|
{
|
|
<span style=color:#66d9ef>internal</span> <span style=color:#66d9ef>procedure</span> BlockCustomer<span style=color:#f92672>(</span><span style=color:#66d9ef>var</span> Cust: <span style=color:#66d9ef>Record</span> Customer; HideDialog: <span style=color:#66d9ef>Boolean</span><span style=color:#f92672>)
|
|
</span><span style=color:#f92672> </span><span style=color:#66d9ef>var</span>
|
|
IsHandled: <span style=color:#66d9ef>Boolean</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
<span style=color:#66d9ef>if</span> <span style=color:#f92672>not</span> ConfirmBlockCustomer<span style=color:#f92672>(</span>HideDialog<span style=color:#f92672>) </span><span style=color:#66d9ef>then</span> <span style=color:#66d9ef>exit</span>;
|
|
OnBeforeBlockCustomer<span style=color:#f92672>(</span>Cust, IsHandled<span style=color:#f92672>)</span>;
|
|
DoBlockCustomer<span style=color:#f92672>(</span>Cust, IsHandled<span style=color:#f92672>)</span>;
|
|
OnAfterBlockCustomer<span style=color:#f92672>(</span>Cust<span style=color:#f92672>)</span>;
|
|
AcknowledgeBlockCustomer<span style=color:#f92672>(</span>HideDialog<span style=color:#f92672>)
|
|
</span><span style=color:#f92672> </span><span style=color:#66d9ef>end</span>;
|
|
|
|
<span style=color:#66d9ef>local</span> <span style=color:#66d9ef>procedure</span> DoBlockCustomer<span style=color:#f92672>(</span><span style=color:#66d9ef>var</span> Cust: <span style=color:#66d9ef>Record</span> Customer; IsHandled: <span style=color:#66d9ef>Boolean</span><span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
<span style=color:#66d9ef>if</span> IsHandled <span style=color:#66d9ef>then</span>
|
|
<span style=color:#66d9ef>exit</span>;
|
|
|
|
Cust<span style=color:#f92672>.</span>Blocked <span style=color:#f92672>:=</span> Cust<span style=color:#f92672>.</span>Blocked::All;
|
|
Cust<span style=color:#f92672>.</span><span style=color:#66d9ef>Modify</span><span style=color:#f92672>(</span>true<span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>end</span>;
|
|
|
|
<span style=color:#66d9ef>local</span> <span style=color:#66d9ef>procedure</span> ConfirmBlockCustomer<span style=color:#f92672>(</span>HideDialog: <span style=color:#66d9ef>Boolean</span><span style=color:#f92672>)</span>: <span style=color:#66d9ef>Boolean</span>
|
|
<span style=color:#66d9ef>var</span>
|
|
ConfirmManagement: <span style=color:#66d9ef>Codeunit</span> "Confirm Management";
|
|
ConfirmQst: <span style=color:#66d9ef>Label</span> <span style=color:#e6db74>'Are you sure?'</span>;
|
|
DefaultAnswer: <span style=color:#66d9ef>Boolean</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
DefaultAnswer <span style=color:#f92672>:=</span> true;
|
|
|
|
<span style=color:#66d9ef>if</span> HideDialog <span style=color:#66d9ef>then</span> <span style=color:#66d9ef>exit</span><span style=color:#f92672>(</span>DefaultAnswer<span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>exit</span><span style=color:#f92672>(</span>ConfirmManagement<span style=color:#f92672>.</span>GetResponseOrDefault<span style=color:#f92672>(</span>ConfirmQst, DefaultAnswer<span style=color:#f92672>))</span>;
|
|
<span style=color:#66d9ef>end</span>;
|
|
|
|
<span style=color:#66d9ef>local</span> <span style=color:#66d9ef>procedure</span> AcknowledgeBlockCustomer<span style=color:#f92672>(</span>HideDialog: <span style=color:#66d9ef>Boolean</span><span style=color:#f92672>)
|
|
</span><span style=color:#f92672> </span><span style=color:#66d9ef>var</span>
|
|
AcknowledgeMsg: <span style=color:#66d9ef>Label</span> <span style=color:#e6db74>'You successfully executed "BlockCustomer"'</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
<span style=color:#66d9ef>if</span> <span style=color:#f92672>not</span> GuiAllowed <span style=color:#f92672>or</span> HideDialog <span style=color:#66d9ef>then</span> <span style=color:#66d9ef>exit</span>;
|
|
Message<span style=color:#f92672>(</span>AcknowledgeMsg<span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>end</span>;
|
|
|
|
[IntegrationEvent<span style=color:#f92672>(</span>false, false<span style=color:#f92672>)</span>]
|
|
<span style=color:#66d9ef>local</span> <span style=color:#66d9ef>procedure</span> OnBeforeBlockCustomer<span style=color:#f92672>(</span><span style=color:#66d9ef>var</span> Cust: <span style=color:#66d9ef>Record</span> Customer; <span style=color:#66d9ef>var</span> IsHandled: <span style=color:#66d9ef>Boolean</span><span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
<span style=color:#66d9ef>end</span>;
|
|
|
|
[IntegrationEvent<span style=color:#f92672>(</span>false, false<span style=color:#f92672>)</span>]
|
|
<span style=color:#66d9ef>local</span> <span style=color:#66d9ef>procedure</span> OnAfterBlockCustomer<span style=color:#f92672>(</span><span style=color:#66d9ef>var</span> Cust: <span style=color:#66d9ef>Record</span> Customer<span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
<span style=color:#66d9ef>end</span>;
|
|
}
|
|
</code></pre></div><p>Within that codeunit, the pattern is always the same:</p>
|
|
<ul>
|
|
<li>One public (internal) procedure</li>
|
|
<li>The rest is always local</li>
|
|
</ul>
|
|
<p>So, from outside the codeunit, there is only one clear entrypoint: that one (public) internal function with its parameters.</p>
|
|
<p>The <strong>pattern</strong> within the codeunit exists of a few layers:</p>
|
|
<ul>
|
|
<li>The UI layer</li>
|
|
<li>The Event layer</li>
|
|
<li>The method layer</li>
|
|
</ul>
|
|
<p><em>The UI layer</em>
|
|
The UI layer takes care of the UI, obviously. What is important in this case, is that you always make sure that there is a “HideDialog” parameter that the business logic can use to still decide whether to use the dialog or not.</p>
|
|
<p>These are the UI Layer parts, where you see the public function gets the HideDialog, and passes it to the UI-related procedures, where the business logic for showing the UI takes place. Also, the default answer of the confirmation is handled there as well (what if the business logic calls this method with HideDialog to “true”).</p>
|
|
<div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-AL data-lang=AL><span style=color:#66d9ef>codeunit</span> <span style=color:#ae81ff>53100</span> "WLD BlockCustomer Meth"
|
|
{
|
|
<span style=color:#66d9ef>internal</span> <span style=color:#66d9ef>procedure</span> BlockCustomer<span style=color:#f92672>(</span><span style=color:#66d9ef>var</span> Cust: <span style=color:#66d9ef>Record</span> Customer; HideDialog: <span style=color:#66d9ef>Boolean</span><span style=color:#f92672>)
|
|
</span><span style=color:#f92672> </span><span style=color:#66d9ef>var</span>
|
|
IsHandled: <span style=color:#66d9ef>Boolean</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
<span style=color:#66d9ef>if</span> <span style=color:#f92672>not</span> ConfirmBlockCustomer<span style=color:#f92672>(</span>HideDialog<span style=color:#f92672>) </span><span style=color:#66d9ef>then</span> <span style=color:#66d9ef>exit</span>;
|
|
<span style=color:#f92672>...
|
|
</span><span style=color:#f92672> </span>AcknowledgeBlockCustomer<span style=color:#f92672>(</span>HideDialog<span style=color:#f92672>)
|
|
</span><span style=color:#f92672> </span><span style=color:#66d9ef>end</span>;
|
|
<span style=color:#f92672>...
|
|
</span><span style=color:#f92672>
|
|
</span><span style=color:#f92672> </span><span style=color:#66d9ef>local</span> <span style=color:#66d9ef>procedure</span> ConfirmBlockCustomer<span style=color:#f92672>(</span>HideDialog: <span style=color:#66d9ef>Boolean</span><span style=color:#f92672>)</span>: <span style=color:#66d9ef>Boolean</span>
|
|
<span style=color:#66d9ef>var</span>
|
|
ConfirmManagement: <span style=color:#66d9ef>Codeunit</span> "Confirm Management";
|
|
ConfirmQst: <span style=color:#66d9ef>Label</span> <span style=color:#e6db74>'Are you sure?'</span>;
|
|
DefaultAnswer: <span style=color:#66d9ef>Boolean</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
DefaultAnswer <span style=color:#f92672>:=</span> true;
|
|
|
|
<span style=color:#66d9ef>if</span> HideDialog <span style=color:#66d9ef>then</span> <span style=color:#66d9ef>exit</span><span style=color:#f92672>(</span>DefaultAnswer<span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>exit</span><span style=color:#f92672>(</span>ConfirmManagement<span style=color:#f92672>.</span>GetResponseOrDefault<span style=color:#f92672>(</span>ConfirmQst, DefaultAnswer<span style=color:#f92672>))</span>;
|
|
<span style=color:#66d9ef>end</span>;
|
|
|
|
<span style=color:#66d9ef>local</span> <span style=color:#66d9ef>procedure</span> AcknowledgeBlockCustomer<span style=color:#f92672>(</span>HideDialog: <span style=color:#66d9ef>Boolean</span><span style=color:#f92672>)
|
|
</span><span style=color:#f92672> </span><span style=color:#66d9ef>var</span>
|
|
AcknowledgeMsg: <span style=color:#66d9ef>Label</span> <span style=color:#e6db74>'You successfully executed "BlockCustomer"'</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
<span style=color:#66d9ef>if</span> <span style=color:#f92672>not</span> GuiAllowed <span style=color:#f92672>or</span> HideDialog <span style=color:#66d9ef>then</span> <span style=color:#66d9ef>exit</span>;
|
|
Message<span style=color:#f92672>(</span>AcknowledgeMsg<span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>end</span>;
|
|
<span style=color:#f92672>...
|
|
</span><span style=color:#f92672></span>}
|
|
</code></pre></div><p><em>The Event layer</em>
|
|
This layer is going to add flexibility to any app that has a dependency on this app. By default, the pattern always foresees an <code>OnBefore</code> and an <code>OnAfter</code> event.</p>
|
|
<p>This is the relevant code for the event layer:</p>
|
|
<div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-AL data-lang=AL><span style=color:#66d9ef>codeunit</span> <span style=color:#ae81ff>53100</span> "WLD BlockCustomer Meth"
|
|
{
|
|
<span style=color:#66d9ef>internal</span> <span style=color:#66d9ef>procedure</span> BlockCustomer<span style=color:#f92672>(</span><span style=color:#66d9ef>var</span> Cust: <span style=color:#66d9ef>Record</span> Customer; HideDialog: <span style=color:#66d9ef>Boolean</span><span style=color:#f92672>)
|
|
</span><span style=color:#f92672> </span><span style=color:#66d9ef>var</span>
|
|
IsHandled: <span style=color:#66d9ef>Boolean</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
<span style=color:#f92672>...
|
|
</span><span style=color:#f92672> </span>OnBeforeBlockCustomer<span style=color:#f92672>(</span>Cust, IsHandled<span style=color:#f92672>)</span>;
|
|
<span style=color:#f92672>...
|
|
</span><span style=color:#f92672> </span>OnAfterBlockCustomer<span style=color:#f92672>(</span>Cust<span style=color:#f92672>)</span>;
|
|
<span style=color:#f92672>...
|
|
</span><span style=color:#f92672> </span><span style=color:#66d9ef>end</span>;
|
|
<span style=color:#f92672>...
|
|
</span><span style=color:#f92672> </span>[IntegrationEvent<span style=color:#f92672>(</span>false, false<span style=color:#f92672>)</span>]
|
|
<span style=color:#66d9ef>local</span> <span style=color:#66d9ef>procedure</span> OnBeforeBlockCustomer<span style=color:#f92672>(</span><span style=color:#66d9ef>var</span> Cust: <span style=color:#66d9ef>Record</span> Customer; <span style=color:#66d9ef>var</span> IsHandled: <span style=color:#66d9ef>Boolean</span><span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
<span style=color:#66d9ef>end</span>;
|
|
|
|
[IntegrationEvent<span style=color:#f92672>(</span>false, false<span style=color:#f92672>)</span>]
|
|
<span style=color:#66d9ef>local</span> <span style=color:#66d9ef>procedure</span> OnAfterBlockCustomer<span style=color:#f92672>(</span><span style=color:#66d9ef>var</span> Cust: <span style=color:#66d9ef>Record</span> Customer<span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
<span style=color:#66d9ef>end</span>;
|
|
}
|
|
</code></pre></div><p><em>The method layer</em>
|
|
The last layer is obviously where the business logic will be written.</p>
|
|
<p>The relevant part is:</p>
|
|
<div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-AL data-lang=AL><span style=color:#66d9ef>codeunit</span> <span style=color:#ae81ff>53100</span> "WLD BlockCustomer Meth"
|
|
{
|
|
<span style=color:#66d9ef>internal</span> <span style=color:#66d9ef>procedure</span> BlockCustomer<span style=color:#f92672>(</span><span style=color:#66d9ef>var</span> Cust: <span style=color:#66d9ef>Record</span> Customer; HideDialog: <span style=color:#66d9ef>Boolean</span><span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>var</span>
|
|
IsHandled: <span style=color:#66d9ef>Boolean</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
<span style=color:#f92672>...
|
|
</span><span style=color:#f92672> </span>DoBlockCustomer<span style=color:#f92672>(</span>Cust, IsHandled<span style=color:#f92672>)</span>;
|
|
<span style=color:#f92672>...
|
|
</span><span style=color:#f92672> </span><span style=color:#66d9ef>end</span>;
|
|
|
|
<span style=color:#66d9ef>local</span> <span style=color:#66d9ef>procedure</span> DoBlockCustomer<span style=color:#f92672>(</span><span style=color:#66d9ef>var</span> Cust: <span style=color:#66d9ef>Record</span> Customer; IsHandled: <span style=color:#66d9ef>Boolean</span><span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>begin</span>
|
|
<span style=color:#66d9ef>if</span> IsHandled <span style=color:#66d9ef>then</span>
|
|
<span style=color:#66d9ef>exit</span>;
|
|
|
|
Cust<span style=color:#f92672>.</span>Blocked <span style=color:#f92672>:=</span> Cust<span style=color:#f92672>.</span>Blocked::All;
|
|
Cust<span style=color:#f92672>.</span><span style=color:#66d9ef>Modify</span><span style=color:#f92672>(</span>true<span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>end</span>;
|
|
<span style=color:#f92672>...
|
|
</span><span style=color:#f92672></span>}
|
|
</code></pre></div><p>Usually indicated with a “do”-function, the business logic takes place in that procedure. Obviously, when you have a decent amount of code, it’s recommended that you make it readable by applying all the Best Practices in terms of readability in the codeunit. Though, a few pointers here:</p>
|
|
<ul>
|
|
<li>keep the <a href=https://en.wikipedia.org/wiki/Cyclomatic_complexity>cyclomatic complexity</a> low
|
|
<ul>
|
|
<li>one line (function call) after an IF-clause</li>
|
|
<li>one line (function call) after a repeat</li>
|
|
</ul>
|
|
</li>
|
|
<li>readable function calls</li>
|
|
<li>…</li>
|
|
</ul>
|
|
<p><strong>Call out to the method from a table</strong></p>
|
|
<p>Now, there is a reason that the one global procedure in the method-codeunit is <code>internal</code>. We shouldn’t be calling this procedure directly. We should be calling it through it’s “class” (usually, a table can be seen as a class). That means, we would have to create a public (not internal) procedure on table-level, which can be used in the business logic.</p>
|
|
<p>In our example above, this could be that table extension:</p>
|
|
<div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-AL data-lang=AL><span style=color:#66d9ef>tableextension</span> <span style=color:#ae81ff>53100</span> "Customer Ext BASE" <span style=color:#66d9ef>extends</span> Customer
|
|
{
|
|
<span style=color:#66d9ef>procedure</span> BlockCustomer<span style=color:#f92672>(</span>HideDialog: <span style=color:#66d9ef>Boolean</span><span style=color:#f92672>)
|
|
</span><span style=color:#f92672> </span><span style=color:#66d9ef>var</span>
|
|
WLDBlockCustomerMeth: <span style=color:#66d9ef>Codeunit</span> "WLD BlockCustomer Meth";
|
|
<span style=color:#66d9ef>begin</span>
|
|
WLDBlockCustomerMeth<span style=color:#f92672>.</span>BlockCustomer<span style=color:#f92672>(</span>Rec, HideDialog<span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>end</span>;
|
|
|
|
<span style=color:#66d9ef>procedure</span> BlockCustomer<span style=color:#f92672>()
|
|
</span><span style=color:#f92672> </span><span style=color:#66d9ef>begin</span>
|
|
BlockCustomer<span style=color:#f92672>(</span>false<span style=color:#f92672>)</span>;
|
|
<span style=color:#66d9ef>end</span>;
|
|
}
|
|
</code></pre></div><p>This practice improves readability. In fact, by doing this, you just extended the suggestions-list in VSCode (IntelliSense) indicating a new method that your class can do. This is very convenient for the developer that might need your new method.</p>
|
|
<p><em>Note - it could very well be that there simply isn’t any table that can act as a class for our method. In that case, you could use a codeunit as well.</em></p>
|
|
<p><strong>Naming Conventions</strong></p>
|
|
<p>You might have noticed that the naming of our method is quite strict:</p>
|
|
<ul>
|
|
<li>codeunit name: <code>WLD BlockCustomer Meth</code></li>
|
|
<li>internal proc: <code>BlockCustomer</code></li>
|
|
<li>do-procedure: <code>DoBlockCustomer</code></li>
|
|
</ul>
|
|
<p>It is important to align these namings. It indicates that the codeunit only does one thing (remember: encapsulation), and it improves searchability from outside the codeunit (for example when you’re searching symbols or something).</p>
|
|
<h2 id=usage>Usage</h2>
|
|
<p>Currently, there is no usage of this pattern in the BaseApp.</p>
|
|
<p>The pattern has a main advantage in an ISV product, just because of the decoupling and extensibility. Although, I have seen many occasions where parts of the pattern was useful on PTE’s as well. You simply never know if ever at the customer site, there is going to be another partner that needs to create its own PTE, and has to depend on yours. So I’d say, this pattern is everywhere applicable, no matter the type of the app.</p>
|
|
<h2 id=benefits>Benefits</h2>
|
|
<p>As I said, it will facilitate a lot of advantages. Let’s explain a bit more in depth:</p>
|
|
<h3 id=extensibility>Extensibility</h3>
|
|
<p>Thanks to the <em>event layer</em>, by applying this pattern for all methods, we will automatically have the bare minimum of events that we need to hook into a method: the <code>OnBefore-</code> and the <code>OnAfter</code>. Of course it would make sense to even add more events to the method when appropriate (eg, when you’re inserting a record in a table, it might be interesting to also raise an event just before you call the insert).</p>
|
|
<h3 id=decoupling>Decoupling</h3>
|
|
<p>Thanks to these same events, and the fact the pattern foresees a handler as well, we are able to “decouple” our method as well. What do I mean with that? Well, we can simply subscribe to the <code>OnBefore</code>event, and set <code>IsHandled</code> to <code>true</code>. This means it will never execute the do-procedure, which means, the original procedure/method/business logic is “decoupled”.</p>
|
|
<p>We can use this obviously for implementing our own method (a new way to accomplish this method), or to disable the method by simply subscribing to it, and only providing the <code>IsHandled := true</code> in our subscriber. However, there are many more usages where we can use this for.</p>
|
|
<p>Maybe one more example:
|
|
if you would apply this pattern to your product, at the customer, you’ll be able to hotfix your methods simply by decoupling them and fixing the method instead of waiting for a hotfix from the hotfix-departement.</p>
|
|
<p>This gives a lot of flexibility.</p>
|
|
<h3 id=readability>Readability</h3>
|
|
<p>When we talk about readability, we actually talk about the part where we expose our method on the class. The rule is: never call the codeunit, but only from one place: from its “class” - or in BC terms: its table (or codeunit).</p>
|
|
<p>In terms of readability, that means that intellisense comes into play. In stead of:</p>
|
|
<div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-AL data-lang=AL><span style=color:#66d9ef>Codeunit</span><span style=color:#f92672>.</span>Run<span style=color:#f92672>(</span><span style=color:#66d9ef>Codeunit</span>::"Sales-Post", SalesHeader<span style=color:#f92672>)</span>;
|
|
</code></pre></div><p>you simply get</p>
|
|
<div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-AL data-lang=AL>SalesHeader<span style=color:#f92672>.</span>Post<span style=color:#f92672>()</span>;
|
|
</code></pre></div><p>THAT is readable. The previous is not! That is just something we got used to.</p>
|
|
<h3 id=testability>Testability</h3>
|
|
<p>There are two things in terms of testability where this pattern helps a lot.</p>
|
|
<p><em>Unit testing</em>
|
|
You can interpret “unit testing” very broadly. But just imagine: when you’re building your software entirely out of “methods” - which means: when you’d build your software entirely with this “Generic Method Pattern”. Now, the list of methods, are all the units that you need to test: if you test all your methods, you kind of like test the majority of your software, right?</p>
|
|
<p>So you could simply set up rules in your company like: EVERY method needs a test-codeunit. And even more: since every method only has one global function - it’s pretty easy to know the context, and all the flavors to test your method.</p>
|
|
<p>The pattern describes the tests that needs to be written.</p>
|
|
<p><em>Disabling methods</em>
|
|
Coming back to the “decoupling” part - in tests, you actually might need it more than you realize. Just imagine: you want to test method 1, but method 2 comes in the way by interfering with configurations that you need to do, or UI that is popping up, while it could be completely pointless.<br>
|
|
Solution: simply - within your test-codeunit - subscribe (with a manual subscriber) to method 2, set <code>IsHandled</code> to <code>false</code> - done!</p>
|
|
<h3 id=encapsulation>Encapsulation</h3>
|
|
<p>Don’t underestimate the power of the encapsulation part of this pattern. One of the first questions that people ask themselves when reading into this pattern is: “<em>isn’t it going to consume all my codeunit-id’s</em>” or “<em>so many codeunits, that can’t be readable, right?</em>”.<br>
|
|
The fact that the functionality of one method is encapsulated in one codeunit is very powerful. You’ll avoid <a href=https://sourcemaking.com/antipatterns/boat-anchor>Boat anchors</a> simply because because, thanks to the encapsulation, there is a limited amount of code in the codeunit, of course.<br>
|
|
And because of that, it so much more maintainable, upgradable, readable, .. . Only advantages.</p>
|
|
<h2 id=when-not-to-use>When not to use</h2>
|
|
<p>However, there are occasions where you can’t use this pattern. Just imagine if you’d put EVERY SINGE LINE of code in a method, including the simple validation code on a table, or library-functions like in helper codeunits. That would obviously not make any sense.</p>
|
|
<p>So all I can say is: use your common sense.</p>
|
|
<p>One example: set the bar at “validation code”: any code that is solely there to facilitate data integrity doesn’t belong in method codeunits.</p>
|
|
<p>Another tip might be: don’t let the amount of codelines trick you in deciding to <em>not</em> use this pattern: when it’s a method, it’s a method. When it makes sense to be able to extend, decouple, .. then this pattern can help.</p>
|
|
<h2 id=snippets>Snippets</h2>
|
|
<p><a href="https://marketplace.visualstudio.com/items?itemName=waldo.crs-al-language-extension">waldo’s CRS AL Language Extension</a> contains snippets that help you in setting up the boiler plate code in a matter of seconds.</p>
|
|
<p>The snippets are:</p>
|
|
<ul>
|
|
<li><code>tcodeunitMethodWithoutUIwaldo</code></li>
|
|
<li><code>tcodeunitMethodWithUIwaldo</code></li>
|
|
</ul>
|
|
<h2 id=list-of-references>List of references</h2>
|
|
<p>There have been a number of occasions where people have been sharing this pattern. Here is one:</p>
|
|
<div style=position:relative;padding-bottom:56.25%;height:0;overflow:hidden>
|
|
<iframe src=https://www.youtube.com/embed/CWpaD9RUa6U style=position:absolute;top:0;left:0;width:100%;height:100%;border:0 allowfullscreen title="YouTube Video"></iframe>
|
|
</div>
|
|
<h2 id=discussions>Discussions</h2>
|
|
<p>You can discuss this pattern <a href=https://github.com/microsoft/alguidelines/discussions/41>here</a></p>
|
|
<footer class=footline>
|
|
</footer>
|
|
</main>
|
|
</div>
|
|
<div id=navigation>
|
|
<a class="nav nav-prev" href=/bcpatterns/facade-pattern/ title="Facade Pattern"><i class="fa fa-chevron-left"></i></a>
|
|
<a class="nav nav-next" href=/bcbestpractices/ title="BC Dev. Best Practices"><i class="fa fa-chevron-right"></i></a>
|
|
</div>
|
|
</div>
|
|
<div style=left:-1000px;overflow:scroll;position:absolute;top:-1000px;border:none;box-sizing:content-box;height:200px;margin:0;padding:0;width:200px>
|
|
<div style=border:none;box-sizing:content-box;height:200px;margin:0;padding:0;width:200px></div>
|
|
</div>
|
|
<script src=/js/clipboard.min.js?1644959101></script>
|
|
<script src=/js/perfect-scrollbar.min.js?1644959101></script>
|
|
<script src=/js/perfect-scrollbar.jquery.min.js?1644959101></script>
|
|
<script src=/js/jquery.svg.pan.zoom.js?1644959101></script>
|
|
<script src=/js/featherlight.min.js?1644959101></script>
|
|
<script src=/js/modernizr.custom-3.6.0.js?1644959101></script>
|
|
<script src=/js/relearn.js?1644959101></script>
|
|
</body>
|
|
</html> |