In my previous blog, I had explained about Javascript and
business rule. Part 3
In this blog, I will try to focus on Plugin.
I am assuming you have some basic idea of C#.
A plug-in is custom business logic (code) that you can integrate
with Microsoft Dynamics 365 (online & on-premises) to modify or augment the
standard behavior of the platform. Another way to think about plug-ins is that
they are handlers for events fired by Microsoft Dynamics 365. You can
subscribe, or register, a plug-in to a known set of events to have your code
run when the event occurs.
Event execution pipeline
The event execution pipeline processes events either
synchronously or asynchronously. The platform core operation and any plug-ins
registered for synchronous execution are executed immediately
Regardless of whether a plug-in executes synchronously or
asynchronously, there’s a two-minute time limit imposed on the execution of a
(message) request. If the execution of your plug-in logic exceeds the time
limit, a System.TimeoutException is thrown. If a plug-in needs more processing time than
two minutes, consider using a workflow or other background process to
accomplish the intended task. This two-minute time limit applies only to
plug-ins registered to execute under partial trust, also known as the sandbox.
Pipeline
stages
The event pipeline is divided into multiple stages, of which 4
are available to register custom developed or 3rd party plug-ins. Multiple
plug-ins that are registered in each stage can be further be ordered (ranked)
within that stage during plug-in registration.
Event
|
Stage name
|
Stage number
|
Description
|
||
Pre-Event
|
Pre-validation
|
10
|
Stage in the
pipeline for plug-ins that are to execute before the main system operation.
Plug-ins registered in this stage may execute outside the database
transaction.
|
||
Pre-Event
|
Pre-operation
|
20
|
Stage in the
pipeline for plug-ins that are to execute before the main system operation.
Plug-ins registered in this stage are executed within the database
transaction.
|
||
Platform Core
Operation
|
MainOperation
|
30
|
In-transaction main
operation of the system, such as create, update, delete, and so on. No custom
plug-ins can be registered in this stage. For internal use only.
|
||
Post-Event
|
Post-operation
|
40
|
Stage in the
pipeline for plug-ins which are to execute after the main operation. Plug-ins
registered in this stage are executed within the database transaction.
|
Prerequisites
Install Visual studio with .net framework 4.5.2
Download Dynamics CRM SDK(https://www.microsoft.com/en-in/download/details.aspx?id=50032)
Install CRMSDKTemplates (SDK-Templates)
Demo
Open visual studio and select new project.
Select “CRM Developer Extensions” from template and 4.5.2
framework then select “CRM Plug-in Project”.
Than select target SDK version. And click Create Project.
Add new class in your solution.
Add
namespaces
using Microsoft.Xrm.Sdk
using Microsoft.Xrm.Sdk.Query;
using System.Runtime.Serialization;
Add access modifier “Public” before class and Inherit Interface “IPlugin”
public class Myclass:IPlugin
Implement IPlugin interface.
public class Myclass:IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
throw new NotImplementedException();
}
}
Now you need to create object of Trace and service interface.
public class Myclass:IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
try
{
ITracingService trace = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
//
Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
//
Obtain the organization service reference.
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service =
serviceFactory.CreateOrganizationService(context.UserId);
Entity entity=null;
//
The InputParameters collection contains all the data passed in the message
request.
if (context.InputParameters.Contains("Target")
&&context.InputParameters["Target"] is Entity)
{
// Obtain the target entity from the input parameters.
entity = (Entity)context.InputParameters["Target"];
}
// The
InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target")
&& context.InputParameters["Target"] is EntityReference)
{
// Obtain the target entity from the input parameters.
EntityReference
entityReference = (EntityReference)context.InputParameters["Target"];
entity =
service.Retrieve(entityReference.LogicalName, entityReference.Id,new ColumnSet(true));
}
if(entity!=null)
{
//Do
your work
}
}
catch(Exception ex)
{
throw new InvalidPluginExecutionException(ex.Message);
}
}
}
These are the basic code needs in most of plugins.
In //Do your work section you can use your custom
logic like update, assign validation etc.
Use trace.Trace(“your message”); to add message like
console.write(“”) in console application. It will help you to get information
when your plugin throw exception.
Pre and post entity images
PreEntityImages and PostEntityImages contain snapshots of the primary entity's attributes
before (pre) and after (post) the core platform operation.
Registering for pre or post images to
access entity attribute values results in improved plug-in performance as
compared to obtaining entity attributes in plug-in code through RetrieveRequest or RetrieveMultipleRequest requests.
if (context.PreEntityImages.Contains("PreImage")
&& context.PreEntityImages["PreImage"] is Entity)
{
// Obtain the target entity from the Pre Image parameters.
Entity preImageEntity = (Entity)context.PreEntityImages["PreImage"];
}
if (context.PostEntityImages.Contains("PostImage")
&& context.PostEntityImages["PostImage"] is Entity)
{
// Obtain the target entity from the Post Image
parameters.
Entity postImageEntity = (Entity)context.PostEntityImages["PostImage"];
}
Pass data between plug-ins
The name of the parameter that is used for
passing information between plug-ins is SharedVariables. This is a collection of key\value pairs. At run time,
plug-ins can add, read, or modify properties in the SharedVariables collection. This provides a method of information
communication among plug-ins.
Adding shared variable value: -
context.SharedVariables.Add("variableName",”variableValue”);
Getting value from shared variable: -
String sharedVariableValue = context.SharedVariables["variableName"]);
Impersonation in plug-ins
Impersonation is used to
execute business logic (custom code) on behalf of a Microsoft Dynamics 365
system user to provide a desired feature or service for that user. Any business
logic executed within a plug-in, including Web service method calls and data access,
is governed by the security privileges of the impersonated user.
One method to impersonate a
system user within a plug-in is by specifying the impersonated user during
plug-in registration.
Second method to impersonate
plugin via code in Plugin.
IOrganizationService service = serviceFactory.CreateOrganizationService(new
Guid(“impersonated user Guid”));
Note: - Impersonation in
plug-ins is not supported while in offline mode.
Register and Deploy
Plug-Ins
Make sure your plugin should have Private or Public
key.
So build your visual studio
solution(Ctrl+Shift+b).
Now go to your project->bin->debug
folder and check your assembly is created or not. There should have your plugin
assembly(dll).
Now open plugin registration
tool and select “Register new Assembly”.
Now select your assembly and
click on “Register Selected plugin”.
Now right click on your assembly and select “Register new Step”.
Now provide all required
information like message name, primary entity etc. and click on “Register New
Step”.
After adding step, you can register Image in your step.
Now run your event like create/update/delete etc. and enjoy your plugin !!
Now run your event like create/update/delete etc. and enjoy your plugin !!
Supported Execution Mode: -
Plugin Stage
|
Synchronous
|
Asynchronous
|
Pre validation
|
Yes
|
No
|
Pre Operation
|
Yes
|
No
|
Post Operation
|
Yes
|
Yes
|
Supported Images in Plugin: -
Message
|
Stage
|
Pre-Image
|
Post-Image
|
Create
|
PRE
|
No
|
No
|
Create
|
POST
|
No
|
Yes
|
Update
|
PRE
|
Yes
|
No
|
Update
|
POST
|
Yes
|
Yes
|
Delete
|
PRE
|
Yes
|
No
|
Delete
|
POST
|
Yes
|
No
|
If plugin register in Sync mode than it will rollback if error occurred,
but it will not rollback if plugin register in Async mode.
In next blog, I will explain
about Custom Workflow.
Share your feedback.
No comments:
Post a Comment