Improving Ugly Microsoft Dynamics CRM Plugin Code

Posted: May 2, 2017 in code, Dynamics CRM, whutnot

OK, so this post is a variation from the normal (which around here, is silence, ironically enough). Because I wanted to share with those that care a handy pattern that I came up with which dramatically improved my life as a Microsoft Dynamics CRM developer. If you’ve done custom plugin development, you’ve probably come across this horrible monster:

 public void Execute(IServiceProvider serviceProvider) {
    var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
    var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
    var service = factory.CreateOrganizationService(context.UserId); 

    if (context.InputParameters).Containst("Target") && context.InputParameters["Target"] is Entity
    {
        //Do things
    }

Which is a horrible, ugly, messy pattern. It is bad and you should feel bad for using it. Now of course, you can’t have static member variables in a plugin, but don’t let that turn you to the dark side. Instead, I introduced a class called PluginHelper.

 public void Execute(IServiceProvider serviceProvider) {
    var p = new PluginHelper(serviceProvider);

The PluginHelper uses the ServiceProvider in its constructor to populate its member variables, which include the Context, Factory, Service, TracingService, all that good stuff. You can also stop repeating yourself and write common functions as methods on the PluginHelper class, so that A) You can stop all that dang typing, and B) your plugin development will become more efficient in time – If you find yourself repeating a function in multiple plugins, move that function to a method on the PluginHelper!

Even better, most of the time, you can just pass the PluginHelper to your methods, making your signatures much cleaner.

Some of the things that I’ve done include…

//BEFORE:
if (context.InputParameters).Containst("Target") && context.InputParameters["Target"] is Entity
    {
        //Do things
    }
//AFTER:
var target = p.GetTargetEntity();
if (target!=null)
{
    //Do things
}
//BEFORE:
if (target.Contains("AttributeName") && target["AttributeName"]!=null)
    {
        //UGH THIS IS THE WORST AND YOU REPEAT IT A MILLION TIMES
    }
//AFTER:
if (p.HasValue(target, "AttributeName")
{
    //I feel like I just brushed my teeth in the shower!
}

And one of my favorites, because you see it so dang often:

//BEFORE:
if (target.Contains("AttributeName") && target["AttributeName"]!=null)
    {
        otherEntity["OtherAttributeName"] = target["AttributeName];
        //Ok, this is just compounding your mistakes...
    }
    else
    {
        otherEntity["OtherAttributeName"] = null;
    }
//AFTER:
p.SetAttributeValue(target, "AttributeName", otherEntity, "OtherAttributeName", true);

In case you were curious, the signature of SetAttributeValue is:

 public bool SetAttributeValue(Entity sourceEntity, string sourceAttributeName, Entity destinationEntity, string destinationAttributeName, bool nullIfNotProvided)

I’ve listed some other methods/members within the PluginHelper below, but I won’t go into detail on them unless you ask real nice. You can probably guess what they do.

  • GetPreImage
  • AllowTracing
  • PrimaryEntityName
  • MessageName
  • TraceEntity
  • HasAttribute
  • GetCompositeEntity

Anyway, I hope this helps SOMEONE out there make more sense of their custom plugin code. I know that it’s saved my sanity multiple times.

Advertisements
Comments
  1. Debi Joanitis says:

    Genius!

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 )

Google+ photo

You are commenting using your Google+ 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