Dynamics 365 Development Best Practice Guide
This guide provides the best practices you need to optimize the following Dynamics 365 (D365) functions: Solutions, Fields, Relationships, Forms, Views, Model-driven Apps, Processes, Web Resources, and Plug-ins.
Solutions
Adding a prefix to solution components that's relative to you or your organization enables users to quickly identify who created or customized each component.
Customizations created within default solutions cannot be exported or distributed to other environments, and they use the default publisher, leaving components with an unspecified publisher. Create custom components inside custom solutions, and if you need to customize out-of-the-box components, add them to the custom solution before customizing.
Adding detailed descriptions to entities, forms, views, fields, and processes prevents confusion and enables fellow developers to easily identify what each component is for.
Unmanaged solutions can be used to reconfigure the system or set up a new instance if the development environment fails. Managed solutions are used to deploy customizations in higher environments (QA, pre-production, production).
Ribbon Workbench imports entire solutions, recreates each entity ribbon, and then publishes them. Fewer entities reduce ribbon update time.
Fields
Duplicate field names may cause errors while importing data, or confuse users creating personal views, Power Automate flows, and more.
Choose a data type that accurately reflects the data you want to store and supports null values if needed. For example, if time is not required for a date, choose Date Only; if a field allows only two values without any default, choose Option Set.
Alternate keys prevent users from creating records with duplicate field values or combinations of values. Warning: once a key is deployed to a managed environment, it cannot be deleted.
This prevents users from selecting unrelated options from recent searches. For example, if lookups are 'State' and 'City', disable most recently used items on 'City' — otherwise users may select a city from recent searches that is irrelevant to the selected state.
Relationships
Enable field mapping to auto-populate field data from a parent record when a child record is created (common for sub-grids).
Forms
On quick create forms, the Save & Close button does not wait for asynchronous function calls to complete (e.g., a Retrieve Record WebAPI call). If possible, remove asynchronous calls when saving quick create forms and instead execute them on form load or upon change of field values.
Use the JavaScript addOnChange method to bind field onChange events instead of binding them from form properties. This gives you programmatic control over field events.
Views
Special characters in view names may cause issues when importing from Excel.
Optional fields may not have data and may increase the size of the grid to accommodate empty cells.
If you add a parent column to a sub-grid view, the same value appears for all related records. Example: don't add a Country column on a State sub-grid view inside a Country entity.
Adding icons for status, gender, rank, profit/loss, etc. enables users to quickly identify field values at a glance.
This keeps information consistent across both record states.
Model-driven Apps
Use the app's URL suffix to access the app instead of the globally unique identifier (GUID). The URL suffix is more user-friendly.
Processes
Instead of executing moveNext() and movePrevious() from scripts, update custom fields (such as status) directly from scripts. This activates predefined background workflows, plug-ins, and Power Automate flows linked to the BPF entity to update the active stage.
Web Resources
Namespaces ensure JavaScript methods are unique and prevent collisions between identifiers.
Relative paths keep web resource references environment-independent, since absolute paths include the environment name.
This saves time by letting developers quickly reference and reuse common code.
ExecutionContext is the parent object of FormContext, enabling not just form event handlers but also grid event handlers via GridContext.
Bind the preSearch lookup field event only on form load and update a global variable whenever custom filtration changes. This ensures high performance and easy maintenance of lookup filtration code.
Use Xrm.Constants to access constants like attribute required levels (none, required, recommended), attribute types (Boolean, date/time, lookup), and form notification levels (error, warning).
Use Xrm.Navigation.navigateTo to open forms (entity record, entity list, or HTML web resource) as a modal dialog rather than Xrm.Internal.openDialog or jQuery custom dialog frameworks, which are deprecated or unsupported.
Debugging a JavaScript web resource in the console often requires rewriting code. Browser DevTools (Chrome's Run Snippet, Firefox's Scratchpad) run in the page's JavaScript context and are faster than external tools.
Plug-ins
If context.depth is not used, it causes infinite recursive plug-in calls.
Instead of service.Update(case) directly on the loaded entity, create `Entity temp = new Entity('case')`, set only the fields you need, and call service.Update(temp). This avoids unnecessary field updates.
Declare all other helper functions as private. This reduces code duplication and improves performance.
Separating these concerns improves code readability and maintenance.
Microsoft Dynamics CRM plug-ins have a maximum size. Exceeding the limit prevents remaining plug-ins from being imported.
References
- Optimize your Dynamics 365 environment with our 32 best practices — MAQ Software
- Create a solution in Power Apps — Microsoft Docs, last updated June 14, 2023
- Define alternate keys to reference records — Microsoft Docs, last updated March 30, 2023
- Write and register a plug-in (Microsoft Dataverse) – Power Apps — Microsoft Docs, last updated September 8, 2023
- navigateTo (Client API reference) in model-driven apps – Power Apps — Microsoft Docs, last updated November 29, 2022
- Build your first model-driven app — Microsoft Docs, last updated February 22, 2022
- Change the prefix for the default publisher — Microsoft Docs, last updated February 15, 2022
- Default solution vs. custom solution – Power Platform — Microsoft Docs, last updated February 15, 2022
- Create or edit mapping between entity fields — Microsoft Docs, last updated February 15, 2022
- Configure event handlers for a form in Dynamics 365 — Microsoft Docs, last updated February 15, 2022
- Create web resources in Dynamics 365 — Microsoft Docs, last updated February 15, 2022
Need a Dynamics 365 customization audit or development uplift? MAQ Software's Dynamics team can help.
Talk to our team
Dynamics 365 Deployment Best Practices
Deploy Dynamics 365 faster with minimal downtime using our 8 best practices.
Read More