When extending Business Central, using the right design patterns can be a game-changer. In this blog post, I will share valuable insights into best practices for achieving extensibility within Microsoft Business Central.
Why Old Patterns Still Matter
Old coding patterns and practices, while foundational, can also be outdated. The “management codeunit anti-pattern” was a prime example discussed. These so-called “code containers” were once efficient in legacy environments, but today, they tend to violate the single responsibility principle.
Here’s the problem: they’re tough to read, even tougher to maintain, and they cause issues during merges. Moving forward, the strategy is to replace these containers with smaller, purpose-driven units. By doing this, code becomes easier to manage and more predictable.
Newer patterns, like the “orchestra pattern,” help address these issues.
Think of it as a storyboard for visually breaking down logic. For instance, the pattern was used for 1099 tax forms in Business Central to ensure vendors’ invoices were accounted for. The orchestra defines the “story” using contracts and interfaces, keeping responsibilities clean and manageable.
Example for Contracts:
Smart Testing Practices
Testing is key when building scalable apps. To help with test automation, Business Central allows the use of internalsVisibleTo
in the app.json
to grant test libraries access to internal code.
However, be cautious with this feature—it doesn’t make the app foolproof against tampering when IDs are hijacked. (you can create new app with same GUID and internals become visible to you 😁)
To stay on the safe side:
- Remove internal visibility for production builds.
- Use dedicated test libraries separate from the core application code.
This ensures sensitive code remains secure while still supporting robust testing practices.
Simplifying User Selections
Have you ever had a user request to limit dropdown lists to only a few relevant options? Microsoft has integrated a solution for this directly into Business Central. For example, on sales or purchase pages, temporary option lookup buffers can now clean up selection lists dynamically.
In the standard:
This feature ensures dropdowns present only relevant options without overwhelming users with unnecessary selections.
Here’s how it works:
- Extend the
OptionLookupType
enum.
2. Create two subscribers—one to set up the lookup and another to filter values based on context.
3. Replace the original list field with this filtered temporary field on the page.
Temporary Tables Done Right
Temporary tables simplify data manipulation, but improper use can bog down system performance. The classic approach—loading all fields into temporary tables—carries baggage, especially in SaaS environments where shared resources matter.
What’s the smarter approach?
- Only pull the fields you actually need. Use
SetLoadFields
to limit the data. - Use dedicated buffer tables with trimmed-down fields.
This reduces memory usage while keeping performance steady. For developers, the takeaway is clear: fetch less, process efficiently, and always prioritize scalability in your code.
Mastering Manual Subscriptions
Event subscription is central to Business Central extensibility, but not all events need to run all the time. That’s why “manual binding” is such a useful feature.
By default, events automatically bind and remain active. With manual binding, however, you gain more control by activating subscriptions only when truly needed. This reduces memory usage and speeds up processing.
Here’s how it works:
- Use
BindSubscription
to activate the event manually. - Use
UnbindSubscription
when the transaction completes.
This pattern is especially useful for scenarios like preview posting, where collecting data mimics actual posting without executing full logic. It also ensures your code is clean and reusable.
In the standard:
Isolated Events
What if you need an event to run independently without affecting other processes? That’s where isolated events shine. Unlike regular events, isolated events run in a fresh transaction and commit their changes without impacting the main thread.
For example, you can use them to automate actions or reduce locking risks in multi-threaded systems. Though powerful, they must be handled with care due to their implicit commit behavior.
- Non Isolated Event
2. Isolated Event
3. Non Isolated Event After Isolated Event
Conclusion
Design patterns may evolve, but their goal remains the same: to make software scalable, maintainable, and user-friendly. From managing temporary tables to using manual subscriptions, there are plenty of strategies developers can adopt to improve performance and align with modern extensibility standards.
By following these principles and staying open to new ideas like isolated events and orchestra patterns, you can write cleaner, smarter, and more efficient code. After all, the best systems aren’t just built—they’re designed.
What design patterns have you found most effective for extensibility? Share your thoughts!
Subscribe to our email newsletter to get the latest posts delivered right to your email.
Comments