Nov 17, 2013

Plug-in – Check context in Early bound & Late bound approaches

I previously provided a nice descriptive article on developing plug-ins using Dynamics CRM toolkit. I tried the same approach for CRM 2013 online in both early bound and late bound approaches which worked fine. New SDK\Tools\DeveloperToolkit provides the latest toolkit you can install. Then you get the project templates for CRM 2013 in Visual Studio.


Here I am coding to create a task when opportunity is updated.

Early Bound Sample code;

protected void ExecutePostOpportunityUpdate(LocalPluginContext localContext)
{
if (localContext == null)
{
    throw new ArgumentNullException("localContext");
}

IPluginExecutionContext context = localContext.PluginExecutionContext;
IOrganizationService service = localContext.OrganizationService;

if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
    Opportunity _Opportunity = ((Entity)context.InputParameters["Target"]).ToEntity<Opportunity>();
    try
    {
        // Create Task
        Task _task = new Task();
        _task.Subject = "opportunity changed";
        _task.RegardingObjectId = new EntityReference(Opportunity.EntityLogicalName, _Opportunity.Id);
        _task.Description = "Please look into this opportunity changes";
        service.Create(_task);
    }
    catch (FaultException ex)
    {
        throw new InvalidPluginExecutionException("Plug-in error : ", ex);
    }

    finally
    {
        _Opportunity = null;
    }
}
}

Late Bound Sample code;

protected void ExecutePostOpportunityUpdate(LocalPluginContext localContext)
 {
  if (localContext == null)
  {
      throw new ArgumentNullException("localContext");
  }

  IPluginExecutionContext context = localContext.PluginExecutionContext;
  IOrganizationService service = localContext.OrganizationService;

  if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
  {
      Entity entity = (Entity)context.InputParameters["Target"];
     try
      {
          // Create Task
          Entity task = new Entity("task");
          task["subject"] = "opportunity changed (Late)";
          task["regardingobjectid"] = new EntityReference("opportunity", (Guid)entity.Attributes["opportunityid"]);
          task["description"] = "Please look into this opportunity changes";
          service.Create(task);
      }
      catch (FaultException ex)
      {
          throw new InvalidPluginExecutionException("Plug-in error : ", ex);
      }
      finally
      {
          entity = null;
      }
  }
}

Late Bound – Early Bound argument could be as meaningless as Cannon-Nikon argument in photography!

Whatever you do, if you can do it wiser, it matters. Anyway, I am happy to illustrate one simple mistake one could do if not understood clearly, when coding with early bound approach.

When coding plug-ins one of the crucial things is to identify if an attribute exists in the context. Typically, in update message, we need to know if a field is changed by inspecting the context. In late bound, we do it this way and it works fine;

Entity entity = (Entity)context.InputParameters["Target"];
if (entity.Contains("currentsituation"))
{
    //Code
}

In early bound, we usually cast the context in to our entity type.


After casting we see all the fields in intelligence, yet it doesn’t say they are available. They are available only if they exist in the context.

This can be misleading. In other words below is NOT the way to do something if currentsituation field is changed.

Opportunity _Opportunity = ((Entity)context.InputParameters["Target"]).ToEntity<Opportunity>();
if (_Opportunity.CurrentSituation != null)
{
    // Code
}

So, checking the context has to be done in the late bound manner (as shown, using Contains keyword). Keep in mind, when we say field exist in the context, that means “its presence”. Still its value can be NULL or NOT NULL, which has to be checked as next step, depending on your requirement.

No comments:

Post a Comment