Prerequisite:
1. Create a Plugin and keep the plugin assembly ready which you want to register dynamically.
Let's begin with the coding part using the C# console app:
Step 1: Connect to Dynamics 365 using C# and use the same service
reference link: Connect to D365 using C#
Step 2: Follow the below code, on how to register a new Plugin assembly dynamically
using Microsoft.Xrm.Sdk;using Microsoft.Xrm.Sdk.Query;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
namespace ConsoleAppProjects
{
public class RegisterPluginDynamically
{
public static IOrganizationService _orgService = D365ConnectionService.ConnectionService();
/// <summary>
/// Function to Register a new assembly dynamically
/// </summary>
/// <returns></returns>
public static Guid RegisterAssembly()
{
//Add the assemply path where your Plugin project dll is stored
string filePath = @"C:\Dynamics365Plugins\bin\Debug\Dynamics365Plugins.dll";
Guid assemblyId = Guid.Empty;
try
{
var assembly = Assembly.LoadFile(filePath);
string[] props = assembly.GetName().FullName.Split(",=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
//To register new assembly dll pass the below parameter values
Entity assemb = new Entity("pluginassembly");
assemb["name"] = props[0];
assemb["culture"] = props[4];
assemb["version"] = props[2];
assemb["publickeytoken"] = props[6];
assemb["sourcetype"] = new OptionSetValue(0); // 0= database;
assemb["isolationmode"] = new OptionSetValue(2); // 1= none, 2=sandbox
assemb["content"] = Convert.ToBase64String(File.ReadAllBytes(filePath));
assemblyId = _orgService.Create(assemb);
}
catch (Exception)
{
throw;
}
return assemblyId;
}
/// <summary>
/// Function to create a Plugin Type
/// </summary>
/// <param name="assemblyId"></param>
/// <returns></returns>
public static Guid CreatePluginType(Guid assemblyId)
{
try
{
Guid pluginTypeId = Guid.Empty;
//pass the below parameter value for the plugin type
Entity pluginType = new Entity("plugintype");
pluginType["pluginassemblyid"] = new EntityReference("pluginassembly", assemblyId);
pluginType["typename"] = "Dynamics365Plugins.SamplePlugin";
pluginType["friendlyname"] = "Sample Plugin Dynamically";
pluginType["name"] = "Register Plugin";
pluginType["description"] = " Sample Plugin Dynamically";
pluginTypeId = _orgService.Create(pluginType);
return pluginTypeId;
}
catch (InvalidPluginExecutionException invalidPluginExecutionException)
{
throw invalidPluginExecutionException;
}
catch (Exception exception)
{
throw exception;
}
}
/// <summary>
/// FUnction to add sdk plugin steps
/// </summary>
/// <param name="pluginTypeId"></param>
/// <param name="pluginTypeName"></param>
/// <param name="messageName"></param>
/// <param name="entityName"></param>
/// <param name="mode"></param>
/// <param name="stage"></param>
/// <returns></returns>
public static Guid SdkMessageStep(Guid pluginTypeId, string pluginTypeName, string messageName, string entityName, int mode, int stage)
{
try
{
//Call GetsdkmessageId function and get the value and pass it
Guid messageId = GetSdkMessageId(messageName, _orgService);
Guid messageFitlerId = Guid.Empty;
if (entityName != "" && entityName != string.Empty)
{
messageFitlerId = GetSdkMessageFilterId(entityName, messageName, _orgService);
}
else
entityName = "any entity";
if ((pluginTypeId != Guid.Empty && pluginTypeId != null) && (messageId != null && messageId != Guid.Empty))
{
Entity step = new Entity("sdkmessageprocessingstep");
step["name"] = pluginTypeName + ": " + messageName + " of " + entityName;
step["configuration"] = "";
step["invocationsource"] = new OptionSetValue(0);
step["sdkmessageid"] = new EntityReference("sdkmessage", messageId);
step["supporteddeployment"] = new OptionSetValue(0);
step["plugintypeid"] = new EntityReference("plugintype", pluginTypeId);
step["mode"] = new OptionSetValue(mode); //0=sync,1=async
step["rank"] = 1;
step["stage"] = new OptionSetValue(stage); //10-preValidation, 20-preOperation, 40-PostOperation
if (messageFitlerId != null && messageFitlerId != Guid.Empty)
{
step["sdkmessagefilterid"] = new EntityReference("sdkmessagefilter", messageFitlerId);
}
Guid stepId = _orgService.Create(step);
return stepId;
}
return Guid.Empty;
}
catch (InvalidPluginExecutionException invalidPluginExecutionException)
{
throw invalidPluginExecutionException;
}
catch (Exception exception)
{
throw exception;
}
}
/// <summary>
/// Function to get the sdk message Id
/// </summary>
/// <param name="SdkMessageName"></param>
/// <param name="service"></param>
/// <returns></returns>
public static Guid GetSdkMessageId(string SdkMessageName, IOrganizationService service)
{
try
{
//GET SDK MESSAGE QUERY
QueryExpression sdkMessageQueryExpression = new QueryExpression("sdkmessage");
sdkMessageQueryExpression.ColumnSet = new ColumnSet("sdkmessageid");
sdkMessageQueryExpression.Criteria = new FilterExpression
{
Conditions =
{
new ConditionExpression
{
AttributeName = "name",
Operator = ConditionOperator.Equal,
Values = {SdkMessageName}
},
}
};
//RETRIEVE SDK MESSAGE
EntityCollection sdkMessages = service.RetrieveMultiple(sdkMessageQueryExpression);
if (sdkMessages.Entities.Count != 0)
{
return sdkMessages.Entities.First().Id;
}
throw new Exception(String.Format("SDK MessageName {0} was not found.", SdkMessageName));
}
catch (InvalidPluginExecutionException invalidPluginExecutionException)
{
throw invalidPluginExecutionException;
}
catch (Exception exception)
{
throw exception;
}
}
/// <summary>
/// Function to GetSdkMessageFilterId
/// </summary>
/// <param name="EntityLogicalName"></param>
/// <param name="SdkMessageName"></param>
/// <param name="service"></param>
/// <returns></returns>
public static Guid GetSdkMessageFilterId(string EntityLogicalName, string SdkMessageName, IOrganizationService service)
{
try
{
//GET SDK MESSAGE FILTER QUERY
QueryExpression sdkMessageFilterQueryExpression = new QueryExpression("sdkmessagefilter");
sdkMessageFilterQueryExpression.ColumnSet = new ColumnSet("sdkmessagefilterid");
sdkMessageFilterQueryExpression.Criteria = new FilterExpression
{
Conditions =
{
new ConditionExpression
{
AttributeName = "primaryobjecttypecode",
Operator = ConditionOperator.Equal,
Values = {EntityLogicalName}
},
new ConditionExpression
{
AttributeName = "sdkmessageid",
Operator = ConditionOperator.Equal,
Values = {GetSdkMessageId(SdkMessageName,service)}
},
}
};
//RETRIEVE SDK MESSAGE FILTER
EntityCollection sdkMessageFilters = service.RetrieveMultiple(sdkMessageFilterQueryExpression);
if (sdkMessageFilters.Entities.Count != 0)
{
return sdkMessageFilters.Entities.First().Id;
}
throw new Exception(String.Format("SDK Message Filter for {0} was not found.", EntityLogicalName));
}
catch (InvalidPluginExecutionException invalidPluginExecutionException)
{
throw invalidPluginExecutionException;
}
catch (Exception exception)
{
throw exception;
}
}
/// <summary>
/// Function register Images
/// </summary>
/// <param name="stepId"></param>
public static void CreateImage(Guid stepId)
{
try
{
string[] myValues = new string[] { "statecode", "subject", "actualend", "statuscode" };
string csvString = string.Join(",", myValues);
Entity image = new Entity("sdkmessageprocessingstepimage");
image["messagepropertyname"] = "Target";
image["imagetype"] = new OptionSetValue(1);
image["entityalias"] = "Target";
image["name"] = "Target";
image["attributes"] = csvString;
image["sdkmessageprocessingstepid"] = new EntityReference("sdkmessageprocessingstep", stepId);
Guid imageId = _orgService.Create(image);
}
catch (InvalidPluginExecutionException invalidPluginExecutionException)
{
throw invalidPluginExecutionException;
}
catch (Exception exception)
{
throw exception;
}
}
}
}
Step 3: Finally, Create a ConsoleBase Class and add the below code -> this is my main class from where actual execution starts -> I will call all related functions from this class as shown:
using System;namespace ConsoleAppProjects
{
class ConsoleBase
{
static void Main(string[] args)
{
Guid assemblyId = RegisterPluginDynamically.RegisterAssembly();
Guid pluginTypeId = RegisterPluginDynamically.CreatePluginType(assemblyId);
Guid stepId = RegisterPluginDynamically.SdkMessageStep(pluginTypeId, "Dynamics365Plugins.SamplePlugin", "create", "account", 1, 40);
RegisterPluginDynamically.CreateImage(stepId);
}
}
}