Dynamics CRM Model-Driven Apps: How to use executionContext.setSharedVariable and executionContext.getSharedVariable

In my blog post, I had explained how to use setSharedVariable and getSharedVariable functions for plugin development that you can read here. When I check on the documentation in the Client API reference, we also can found there are the same functions that we can use for front-end development (JavaScript) in the executionContext. But the question that directly pop-out in my mind: what are the purpose of these functions? So today this blog post will explain and give you a glimpse of an idea of how we can make use of these functions.

If you open that page, there is no clear definition of the purpose of these functions. Before, I thought I can send some value directly to be used in the plugin or vice versa. But they can’t. Here is the proof for one of the scenarios (sending from JavaScript to Plugin).

From JavaScript code:

var Blog = Blog || {};
(function () {
    this.formOnLoad = function (context) {
        context.setSharedVariable('form-on-load', 'hello');
    };
}).apply(Blog);

From Plugin code:

using Microsoft.Xrm.Sdk;
using System;
using System.Text;
namespace Demo.Plugins
{
    public class DemoPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            var context = (IPluginExecutionContext)
                serviceProvider.GetService(typeof(IPluginExecutionContext));
            var sb = new StringBuilder();
            foreach (var sharedVariable in context.SharedVariables)
            {
                sb.AppendLine($"{sharedVariable.Key}: {sharedVariable.Value.ToString()}");
            }
            throw new InvalidPluginExecutionException("From Plugin: " + sb);
        }
    }
}

When the form loaded and successfully called Blog.formOnLoad method, I try to change an attribute and save it. Here is the result:

No SharedVariable under form-on-load name found.

From here, we know that executionContext.setSharedVariable will not pass data from the front-end to the back-end.

Then I try to change again the scenario. Now I just want to do executionContext.setSharedVariable on form onload, then consume it on new_description changed. Here is the JavaScript code:

var Blog = Blog || {};
var TEST_SHARED_VARIABLE = 'blog-shared-variable';
(function () {
    this.formOnLoad = function (context) {
        context.setSharedVariable(TEST_SHARED_VARIABLE, 'hello');
        var formContext = context.getFormContext();
        formContext.getAttribute('new_description').setValue('from on load');
        console.log('Set on form-onload');
    };
    this.descriptionOnChange = function(context){
        var result = context.getSharedVariable(TEST_SHARED_VARIABLE);
        console.log('Shared-variable:' + result);
    };
}).apply(Blog);

Here is the result after the form loaded and after I change the description:

sharedVariable only can be accessed per executionContext

Now we can conclude that the sharedVariable will be unique per executionContext. Then the question is what can we do with this behavior?

Summary

Here what I think how we can make use of executionContext.setSharedVarible/executionContext.getSharedVariable :

var Blog = Blog || {};
var Business = Blog || {};
var TEST_SHARED_VARIABLE = 'blog-shared-variable';
(function () {
    this.getData = function (context) {
        context.setSharedVariable(TEST_SHARED_VARIABLE, 1);
    };
    this.businessLogic1 = function (context) {
        var result = context.getSharedVariable(TEST_SHARED_VARIABLE);
        context.setSharedVariable(TEST_SHARED_VARIABLE, result + 1);
    };
    this.businessLogic2 = function (context) {
        var result = context.getSharedVariable(TEST_SHARED_VARIABLE);
        context.setSharedVariable(TEST_SHARED_VARIABLE, result + 1);
    };
}).apply(Business);
(function () {
    this.formOnLoad = function (context) {
        Business.getData(context);
        Business.businessLogic1(context);
        Business.businessLogic2(context);
        console.log("Result: "+ context.getSharedVariable(TEST_SHARED_VARIABLE));
    };
}).apply(Blog);

From the top code, here is the result in console:

We can store an object to setSharedVariable and use the value using getSharedVariable

If in one event (for instance formOnLoad or attributeOnChanged) we have a bunch of business logic that depend on 1 value. We can make use of executionContext.setSharedVariable and executionContext.getSharedVariable instead of using local variable. The benefit here is, we already know that every time executionContext being called. It always in a clean state. You can think of this method as a state manager per executionContext.

What you think?

One thought on “Dynamics CRM Model-Driven Apps: How to use executionContext.setSharedVariable and executionContext.getSharedVariable

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.