Showing posts with label Register Plugin Dynamically using C#. Show all posts
Showing posts with label Register Plugin Dynamically using C#. Show all posts

Thursday, March 23, 2023

Register Plugin Dynamically in D365 using C#

 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);
        }
    }

}

Step 4: Now debug or Start and test 
Step 5: Log in to PRT: Plugin Registration Tool and verify your plugin is registered



That's all

Thank you!!!