Dynamics CRM Model-Driven Apps: Strategy for Multiple Environment + Solution Layering in Javascript

If you ever make a product based on Dynamics CRM and needs to use multiple environments + solutions for multiple projects. But still willing to achieve tidy + clean solutions when registering events. Here is my recommendation on how to do it without needing to heavily rely on Form registering (no need afraid that the state of the form changed from 1 solution to the other solution become unmanaged).

Here are the examples of the solution dependencies (Solution B depend on Solution A, Solution A depend on Solution Core) and how the events are staked with each other. With this dependency, the business goal is to have an output for the environment with Solution Core installed only, Solution Core + Solution A, and Solution Core + Solution A + Solution B. To make it easy to understand, let’s say you want to make a Core Solution, an Accounting Solution on top of the Core Solution, and a POS Solution on top of an Accounting Solution.

Sample of solution layering

For example, you have Core, Solution A, and Solution B. The details of the events on formOnLoad for each of the solutions are:

  • Core: methodA
  • Environment A (Solution Core + Solution A): methodA, methodB
  • Environment C (Solution Core + Solution A + Solution C): methodA, methodB, methodC

So the idea to make it works is to rely on the list of the methods that we needed to set in one object (in the onLoad event) and register another method to execute all those events using formContext.data.addOnLoad. So with this strategy, we make sure we only have 1 trigger event but can have multiple registering methods in each of the solutions layered.

Here is the sample of the code to achieve that (for simplified the javascript, I just put it in one single file. But in the real world scenario, you must create multiple javascript for it):

var Blog = Blog || {};
Blog.Events = Blog.Events || {};
Blog.Business = Blog.Business || {};
var eventManager = eventManager || {};
var cacheObj = {};

(function() {
    this.set = function(name, values) {
        cacheObj[name] = values;
    };
    this.get = function(name) {
        return cacheObj[name];
    };
}).apply(eventManager);

const FORM_ONLOAD_KEY = 'form-on-load';
(function() {
    this.methodA = function(context) {
        console.log('methodA');
    };
    this.methodB = function(context) {
        console.log('methodB');
    };
    this.methodC = function(context) {
        console.log('methodC');
    };
    this.registerExecuteFormOnLoad = function(context) {
        var executeMethods = function() {
            const methods = eventManager.get(FORM_ONLOAD_KEY);
            for (let i in methods) {
                methods[i](context);
            }
        };
        return function() {
            var formContext = context.getFormContext();
            formContext.data.addOnLoad(executeMethods);
        }();
    };
}).apply(Blog.Business);

(function() {
    this.form_OnLoad = function(context) {
        eventManager.set(FORM_ONLOAD_KEY, [Blog.Business.methodA]);
        Blog.Business.registerExecuteFormOnLoad(context);
    };
    this.form_OnLoadEnvironmentA = function(context) {
        eventManager.set(FORM_ONLOAD_KEY, [Blog.Business.methodA, Blog.Business.methodB]);
    };
    this.form_OnLoadEnvironmentB = function(context) {
        eventManager.set(FORM_ONLOAD_KEY, [Blog.Business.methodC]);
    };
}).apply(Blog.Events);

Here is the sample of the code to achieve that (for simplified the javascript, I just put it in one single file. But in the real world scenario, you must create multiple javascript for it):
Because we are using formContext.data.addOnLoad, this method will be called in the last order (after all the methods that we registered in formOnLoad being called).

Here is the sample of the events registered in the form_onLoad on environment B (Core + Solution A + Solution B):

Events registered on environment B

This is the result on environment B:

Result on load for Environment B

Summary

With this strategy, you can have more dynamics + flexible solution layering without needed too much to register your events in the form. You can also leverage this solution to handling other events as well (attributeOnChanged, formOnSave, etc) using the same method. You only need to register all the events in a different key and modified Blog.Business.registerExecuteFormOnLoad(context) to accept the key to getting all the methods that you need to execute.

What do you think?

2 thoughts on “Dynamics CRM Model-Driven Apps: Strategy for Multiple Environment + Solution Layering in Javascript

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.