clicksor

Sunday, August 12, 2012

MS CRM: Plug-ins 3.0, 4.0 & 2011 with examples

Plug-ins Over view



Plug-ins : In MS-CRM 3.0 we called as Call-outs


Introduction to Plug-in Development for Microsoft Dynamics CRM 4.0

Summary

Microsoft Dynamics CRM 4.0 on-premise supports extending the platform through the integration of custom business logic known as plug-ins. In Microsoft Dynamics CRM 3.0, these business logic extensions are known as callouts. Plug-ins execute in a richer run-time environment than before and have access to new product capabilities. This article provides an overview of the new plug-in capability, compares plug-ins to callouts, and discusses how to begin learning the new plug-in programming model.

Applies To

Microsoft Dynamics CRM 4.0
Microsoft Visual Studio 2005
Microsoft Visual Studio 2008

Introduction

One method of customizing or extending the functionality of the Microsoft Dynamics CRM 4.0 on-premise product is through the integration of custom business logic (code). It is through this extension capability that you can add new data processing features to the product or alter the way business data is processed by the system. You can also define the specific conditions under which the custom business logic is to execute. Whether you are new to extending Microsoft Dynamics CRM or have been developing 3.0 callouts for some time, this article tells you what you need to know to get started learning about and writing plug-ins.
Microsoft Dynamics CRM Online does not support plug-ins. However, you can extend the functionality of the product by using workflows.

Comparing Plug-ins to Callouts

The programming model for adding business logic extensions to Microsoft Dynamics CRM has changed in the latest Microsoft Dynamics CRM 4.0 SDK release as compared to the 3.0 release. This change was the direct result of customers asking for access to more capabilities and run-time information in plug-in code. In addition, architectural changes and feature additions to Microsoft Dynamics CRM 4.0 necessitated changes to the programming model so that plug-ins could take advantage of the new platform capabilities.
What about your existing callouts? Do you have to throw them away and develop new plug-ins? The good news is that Microsoft Dynamics CRM 4.0 is backwards compatible with the callout programming model. Your existing callouts should continue to work alongside any new plug-ins that you develop as long as you do not use any deprecated features. However, if you want to take advantage of the new Microsoft Dynamics CRM 4.0 capabilities and the rich information that is available at run time, you need to make use of the plug-in programming model.
The following points highlight what has changed when comparing the new plug-in programming model to the previous callout model.
  • Registration
    Callouts are registered by editing an XML configuration file that is stored in a specific folder on the Microsoft Dynamics CRM 3.0 server. In essence this is a static registration method. Changes to the configuration file require an IIS reset to apply the changes.
    Plug-ins are registered dynamically through a new registration API. No IIS reset is required. Sample tools to register plug-ins, complete with source code, are provided in the SDK.
  • Context
    Callouts received a basic amount of data at run-time about the user who initiated an operation in Microsoft Dynamics CRM and the entity being acted upon.
    Plug-ins receive a wealth of information at run-time. For more information, see the following What’s New topic.
  • Supported messages
    Callouts could only be executed in response to a subset of messages that were processed by the Microsoft Dynamics CRM platform.
    Plug-ins can execute in response to most messages being processed by the platform.
  • Mode of execution
    Callouts were executed synchronously as part of the main execution thread of the platform. Callouts that performed a lot of processing could reduce overall system performance.
    Plug-ins can execute both synchronously and asynchronously. Asynchronous registered plug-ins are queued to execute at a later time and can incorporate process-intensive operations.

What’s New

In addition to the plug-in features mentioned in the previous topic, the following capabilities are also supported.
  • Infinite loop detection and prevention
    The Microsoft Dynamics CRM platform has the ability to terminate a plug-in that performs an operation that causes the plug-in to be executed repeatedly, resulting in a significant performance hit on the system.
  • Plug-ins receive expanded run-time information (context)
    Information passed to plug-ins include: custom data, the conditions under which the plug-in was run, information included in the request and response messages that the system is processing, and snapshots of entity attributes before and after the core system operation. Plug-ins can also pass data between themselves.
  • Execution dependency
    Plug-ins can be registered so as to be dependent with other plug-ins. Dependency defines an order to plug-in execution whereby one plug-in must run to completion before another plug-in executes.
  • Database deployment
    Plug-ins can be deployed to the Microsoft Dynamics CRM database in addition to on-disk and GAC deployment. Deploying a plug-in to the database enables automatic distribution of the plug-in to multiple Microsoft Dynamics CRM servers in a data center.
  • Offline execution
    Plug-ins can be deployed to Microsoft Dynamics CRM for Outlook with Offline Access and execute while Outlook is in offline mode.

A Sample Plug-in

So you now know about the powerful plug-in capabilities and the extensive data passed to a plug-in at run-time. But what does plug-in code look like? Here is a very basic plug-in that displays "Hello world!" in a dialog to the user.
C#
using System;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
 
namespace MyPlugins
{
   public class HelloWorldPlugin: IPlugin
   {
      public void Execute(IPluginExecutionContext context)
      {
         // Call the Microsoft Dynamics CRM Web services here or perform
         // some other useful work.
         throw new InvalidPluginExecutionException("Hello world!");
      }
   }
}
The real power of plug-ins lies in the extensive context information that is passed to the plug-in, the ability to alter some of that information as it passes through the system, and the ability to call Microsoft Dynamics CRM Web methods. For more information, refer to the SDK documentation.

How to Get Started

Whether you are new to developing Microsoft Dynamics CRM business logic extensions or are an experienced callout developer, the following information should get you up to speed quickly with the new plug-in development and registration programming models.
  • SDK documentation – Contains lots of new material providing detailed information on extending Microsoft Dynamics CRM 4.0. Start by reading the Plug-ins topic.
·         Plug-in Walkthroughs – Follow step by step procedures to write and deploy plug-ins.
·         Quickstart Guide to Plug-in Development – Gets you started developing plug-ins quickly.
  • SDK code samples – Includes sample tools to register plug-ins and also some sample plug-ins. The tool sample code demonstrates how to use the plug-in registration APIs.
If you are new to Microsoft Dynamics CRM SDK programming, you will need to learn about the Web services, security and entity models, and more in order to write plug-ins that perform useful operations. Consult the SDK documentation for more information.

Introduction Plug-ins in detail:

Whenever we need a functionality that isn’t out-of-box, we can add custom business logic which can be called before or after the core platform operation. For e.g. we may want to check the values entered by the user in a form before saving it.

There are many ways of extending the functionality of Microsoft Dynamics CRM.
Client-side script
Workflows
Custom Workflows
Plug-ins

In this article, we closely observe extending the Microsoft Dynamics CRM using plug-ins.

What is Plug-in?

Plug-in is used to extend the functionality of Microsoft Dynamics CRM.
Plug-in enables us to provide complex business logic when required.
Plug-in is a platform layer component.
Plug-in consists of .Net class libraries.

Steps involved

Develop the plug-in
Register the plug-in using Plug-in Registration Tool
Test & Debug the Plug-in
Fix the bugs and Update the plug-in
Register again

Develop the Plug-in

To develop a plug-in, we have to follow these steps:
            Create a new C# Class Library Project
            Add SDK reference
Add a class which implements IPlugin interface
Define Execute method which consists of core plug-in logic

Execute method will be given a IPluginExecutionContext parameter. This parameter provides access to the context of the plug-in. In other words, the information about the entity which caused the plug-in execution will be present in the context parameter.

Following are the important properties of context object:
InitiatingUserId: Gets the ID of the system user account under which the current pipeline is executing.
InputParameters: Gets the parameters of the request message which triggered the event.
OutputParameters: Gets the properties of the response message which is returned as part of pipeline execution.
PostEntityImages: Gets the properties of the primary entity after the core platform operation has been completed. 
PreEntityImages: Gets the properties of the primary entity before the core platform operation has occurred. 

Following are the methods that are supported by context object
CreateCrmService: Returns an instance of the CrmService Web service.
CreateMetadataService: Returns an instance of the MetadataService Web service.



For example, following plug-in is demonstrates creating a follow up task when an account is created:

public void Execute(IPluginExecutionContext context)
{
    DynamicEntity entity = null;

    // Check if the InputParameters property bag contains a target
    // of the current operation and that target is of type DynamicEntity.
    if (context.InputParameters.Properties.Contains(ParameterName.Target) &&
       context.InputParameters.Properties[ParameterName.Target] is DynamicEntity)
    {
        // Obtain the target business entity from the input parmameters.
        entity =
           (DynamicEntity)context.InputParameters.Properties[ParameterName.Target];

        // (Optional) Test for an entity type and message supported by your plug-in.
        if (entity.Name != EntityName.account.ToString()) { return; }
        if (context.MessageName != MessageName.Create.ToString()) { return; }
    }
    else
    {
        return;
    }

    try
    {
        // Create a task activity to follow up with the account customer in 7 days.
        DynamicEntity followup = new DynamicEntity();
        followup.Name = EntityName.task.ToString();

        followup.Properties = new PropertyCollection();
        followup.Properties.Add(new StringProperty("subject", "Send e-mail to the new
           customer."));
        followup.Properties.Add(new StringProperty("description",
           "Follow up with the customer. Check if there are any new issues that need
           resolution."));

        followup.Properties.Add(new CrmDateTimeProperty("scheduledstart",
            CrmTypes.CreateCrmDateTimeFromUniversal(DateTime.Now.AddDays(7))));
        followup.Properties.Add(new CrmDateTimeProperty("scheduledend",
            CrmTypes.CreateCrmDateTimeFromUniversal(DateTime.Now.AddDays(7))));

        followup.Properties.Add(new StringProperty("category",
    context.PrimaryEntityName));

        // Refer to the new account in the task activity.
        if (context.OutputParameters.Properties.Contains("id"))
        {
            Lookup lookup = new Lookup();
            lookup.Value = new
              Guid(context.OutputParameters.Properties["id"].ToString());
            lookup.type = EntityName.account.ToString();

            followup.Properties.Add(new LookupProperty("regardingobjectid", lookup));
        }

        TargetCreateDynamic targetCreate = new TargetCreateDynamic();
        targetCreate.Entity = followup;

        // Create the request object.
        CreateRequest create = new CreateRequest();
        create.Target = targetCreate;

        // Execute the request.
        ICrmService service = context.CreateCrmService(true);
        CreateResponse created = (CreateResponse)service.Execute(create);
    }
    catch (System.Web.Services.Protocols.SoapException)
    {
        // For this example, just re-throw the exception.
        throw;
    }
}



Registering the Plug-in Images:

            Select the step to which you want to register the image
            Right click and choose Register new image
            Select Pre/Post options
            Enter alias name, this name will be used in the code.
                        e.g. context.PostEntityImages[alias]
                                       context.PreEntityImages[alias]

Registering the Plug-in:

            <Refer the the video>

Debugging the Plug-in:
  1. Register the plug-in assembly.
Copy the assembly to the standard plug-in folder on the server: <crm-root>\Server\bin\assembly. If there is another copy of the assembly at the same location and you cannot overwrite that copy because it is locked by Microsoft Dynamics CRM, run the iisreset program in a command window to free the assembly.
  1. Configure the debugger.
Set a breakpoint in your plug-in code. For an online plug-in, attach the debugger to the w3wp.exe process on the Microsoft Dynamics CRM server. For an offline plug-in, attach the debugger to the Microsoft.Crm.Application.Hoster.exe process. For asynchronous registered plug-ins (or workflow assemblies) attach to the CrmAsyncService.exe process. If there are multiple processes running for the same executable file, attach the debugger to all of them because you do not know which process runs your custom code.
  1. Test the plug-in.
Run the Microsoft Dynamics CRM Web application, or other custom application that uses the SDK, and perform whatever action is required to cause the plug-in to execute. For example, if a plug-in is registered for an account creation event, create a new account.
  1. Debug your plug-in code.
Make any needed changes to your code so that it performs as you want. If the code is changed, compile the code into an assembly and repeat step numbers 1, 3, and 4 in this procedure as necessary. However, if you change the plug-in assembly version number, you must unregister the earlier version of the assembly and register the new version.
  1. Register the plug-in in the database.                                                                                                                      After the edit/compile/deploy/test/debug cycle for your plug-in has been completed, unregister the (on-disk) plug-in assembly and then reregister the plug-in in the Microsoft.

Plug-ins 2011:

A plug-in is custom business logic that can integrate with Microsoft Dynamics
CRM 2011 to modify or augment the standard behavior of the platform.
Plug-ins subscribe to a set of events and run when the events occur. These events
occur regardless of the method that is used to perform the activity so that they are
independent of the user interface.
 During plug-in registration, the event that the
plug-in subscribes to is specified.

Plug-in Basics

Plug-ins have many uses. This includes the following:

• Performing complex platform level data validation
• Performing auto-number generation
• Providing integration with other applications
• Executing complex business logic

Any number of plug-ins can be associated with a given entity and event. When
multiple plug-ins are registered for the same event on the same entity, they are
called in a sequence based on the order specified on the step registration. This
value is specified as the Rank and it is supplied when the plug-in is registered.
This allows developer control over the sequence.

Plug-ins can be written in any Microsoft .NET 4.0 CLR-compliant language.
These include the following:

• Microsoft Visual C#
• Microsoft Visual Basic .NET

Plug-ins not executed by the sandbox or asynchronous service execute under the
security context of the Microsoft Dynamics CRM application pool, CrmAppPool,
as defined in Internet Information Services. By default, CrmAppPool uses the
Network Security account identity. Therefore, it is important to set credentials
correctly. Many times, it might be necessary to impersonate the user whose
actions caused the plug-in to run.


Example: Plug-ins 2011:

This is a step by step guide to create a plug-in in CRM 2011.

1. Create a class library project in vs2010.
2. Sign the assembly by using the Signing tab of the project's properties sheet.
3. Add references to microsoft.crm.sdk.proxy , Microsoft.xrm.sdk ,
System.ServiceModel and System.Runtime.Serialization.
4. Here is code for this tutorial. This plugin will check if the account number
field is empty, create a task for the user to fill this up.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// Microsoft Dynamics CRM namespace(s)
using Microsoft.Xrm.Sdk;
using System.ServiceModel;

namespace CRMPlugin1
{
public class createNote:IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{

// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));


// 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 parmameters.
Entity entity = (Entity)context.InputParameters["Target"];



try
{
//check if the account number exist

if (entity.Attributes.Contains("account number") == false)
{

//create a task
Entity task = new Entity("task");
task["subject"] = "Account number is missing";
task["regardingobjectid"] = new EntityReference("account",new Guid(context.OutputParameters["id"].ToString()));

//adding attribute using the add function
// task["description"] = "Account number is missng for the following account. Please enter the account number";
task.Attributes.Add("description", "Account number is missng for the following account. Please enter the account number");



// Obtain the organization service reference.
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);


// Create the task in Microsoft Dynamics CRM.
service.Create(task);


}
}

catch (FaultException ex)
{
throw new InvalidPluginExecutionException("An error occurred in the plug-in.", ex);
}

}

}
}//end class
}//end name space


5. Compile the code and register it on the registration tool provided with sdk.
6. Register it on the post create event of account entity.
Note :check the sdk for instructions to register a plugin




No comments:

Post a Comment