Tuesday, January 31, 2012

Step by step plugin tutorial using Developer's Toolkit Part 3

This blog is an extension of my last blog Step by step plugin tutorial using Developer's Toolkit Part 2. We used “Create Wrapper” method to generate strongly typed classes. In this blog, we will use OrganizationServiceContext to create “Task” entity instead of using service.Create() method. To use OrganizationServiceContext in the plugin, we need to add reference to Microsoft.Xrm.Sdk.Client at the top of the class.
using Microsoft.Xrm.Sdk.Client;
Now create an instance of OrganizationServiceContext by passing the OrganizationService as shown below
// TODO: Implement your custom Plug-in business logic.
IPluginExecutionContext context = localContext.PluginExecutionContext;
IOrganizationService service = localContext.OrganizationService;
//ITracingService tracingService = localContext.TracingService;
//create a service context
var ServiceContext = new OrganizationServiceContext(service);
Now replace the
service.Create(task);
with
ServiceContext.AddObject(task);
ServiceContext.SaveChanges();
Deploy the plugin and test it.

Advantages of using OrganizationServiceContext

The biggest advantage of using OrganizationServiceContext is that we can track multiple entities/operations and save all the changes with ServiceContext.SaveChanges(); statement. Have a look at this article on MSDN. 

Wednesday, January 18, 2012

Step by step plugin tutorial using Developer's Toolkit Part 2

This is a second part of my last blog step-by-step-plugin-tutorial Developer’s Toolkit Part 1. In the last blog, we created a plugin using late binding. In this blog we use early binding (strongly typed classes) to create the same plugin. This is another advantage of using the Developer’s Toolkit. We can generate the strongly typed classes by click of the mouse. We don’t have to use CrmSvcUtil Command-Line Utility and copy the generated file to our plugin Project. I am going to use the same solution I have used for my last blog.
Please read the last blog before starting this one. Here are the steps.
  1. Open the CRM Explorer. Right Click on the Entities node and select “Generate  Wrapper”. It will generate the strongly type classes and add it to the Plugins project. The name of the generated file will be Entities.cs.c1 c3
  2. Now expand the Entities node. Right Click on Account Entity and select “Create Plug-in”. It will display a following dialog. This time we are creating a plugin on update event. Enter the values as shown the screen shot. You can change the class name if you like and press OK. It will create a new file “PostAccountUpdate.cs” in the plugins project.c4
  3. Open the “PostAccountUpdate.cs” file. Add the reference to Entites.cs file to use the strongly typed classes.
  4. Copy the ExecutePostAccountCreate() function code from PostAccountCreate.cs created in last blog and paste it in ExecutePostAccountUpdate() function of “PostAccountUpdate.cs”.
  5. Replace the following lines in copied code of ExecutePostAccountUpdate() function
    //create a task
    Entity task = new Entity("task");
    task["subject"] = "Account number is missing";
    task["regardingobjectid"] = new EntityReference("account",entity.Id);
    
    //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");
                            
    // Create the task in Microsoft Dynamics CRM.
    service.Create(task);
    
    with
    //create a task
    Task task = new Task();
    task.Subject = "Account number is missing";
    task.RegardingObjectId = new EntityReference("account", new Guid(context.OutputParameters["id"].ToString()));
    task.Description = "Account number is missng for the following account. Please enter the account number";
    
    // Create the task in Microsoft Dynamics CRM.
    service.Create(task);
    
    
    We replaced the Entity object with Task object and we used task.Description in place of task["description"]. Early binding (strongly typed classes provides us all the crm entities objects, their properties and methods.
  6. Now right click on CRM Package project and select deploy. It will register the plugin assembly as well as step for the plugin. Click on CRM Explorer to check the deployed plugin as shown in the following screen shot. There are two plugins registered, one for post update event that we just created and one for post create event we created in last blog. Update an account to test the plugin.       c6

Advantages for using early binding

Here is the link to explain the differences between early binding and late binding. I am listing few of advantages using early binding.
  1. The biggest advantage of using early binding is that we have access to all the CRM entities(account, contact, opportunity, task etc) their attributes and their relationships.In late binding we use the Entity (dynamic entity) to work with all the CRM entities.
  2. Access to visual studio intellisense while writing code.In the following screen shot, we create an instance of Task entity and when we type Task, it will display all the attributes and methods belong to task entity.c5
  3. There are less chances of misspelling the attributes names. Early bound references are checked at compile time. for e.g if we spell the attribute name wrong, you won’t able to compile the code. In late binding, it will hard to find out if we misspell the attribute name as references will be checked at run time.

Monday, January 16, 2012

Step by step plugin tutorial using Developer's Toolkit Part 1

I was looking at developer’s toolkit shipped with CRM2011 SDK. There are few blogs out there on how to create plugins using developer's tool kit. Most of the blogs (more or less) are the copy of  “developer toolkit user's guide” that comes with the toolkit.

Here is link to Sam’s blog that explains each project in developer’s toolkit. MSDN blog also have similar contents. In this blog I am going to create a sample plugin using developer’s toolkit. It is a copy of one of my earlier blog(Step by step plugin tutorial for CRM 2011) .

Install the developer’s toolkit.The Developer toolkit for Microsoft Dynamics CRM 2011 was released as part of UR5 SDK release and is available for download here.


  1. Create a new solution in CRM2011. I named my solution “CRM Plugin Solution”. This is optional but I would recommend you do that.
  2. Open Visual Studio 2010. Select File—New –Project. It will display new project templates dialog as shown in the screen sheet belowp1
  3. Select “Dynamics CRM 2011 Package” project. This is also optional. You can go ahead and select “Dynamics CRM 2011 Plugin Library”, But then you cannot deploy the plugin straight from the Visual Studio. You have to use Plugin Registration tool to register the plugin. Enter the name of project/solution.
  4. VS studio will display following dialog.Enter you CRM 2011 server details.Select the solution name we created in step 1 and click okp2
  5. Now right click on the solution and add “Dynamics CRM 2011 Plugin Library” project to the solution. The plugin project will already have a plugin.cs file.
  6. Now sign the plugin assembly. Right click on Plugin Project and select properties. Select Signing tab from left navigation of project property page. On the Signing tab, select the Sign the assembly check box and set the strong name key file of your choice.At a minimum, you must specify a new key file name. Do not protect your key file by using a password.
  7. If You cannot see the “CRM Explorer” window on the upper left side of the VS studio, click on View menu and select “CRM Explorer”. p3
  8. Now expand “Entities” Node. Right Click the entity on want to create the plugin for and select “Create Plugin”.p4
  9. It will display a following screen.It is equivalent to “Create Step” screen in plugin registration tool. The dialog will pick up the name of the entity and other information. Choose the message and the pipeline stage. You can also change of the Class attribute. Press Ok.pn5
  10. It will create a .cs file with name mentioned in “Class” attribute in screen shot above. Double click on the class file(PostAccountCreate) and scroll down to following lines of code. You write your business logic here.
    protected void ExecutePostAccountCreate(LocalPluginContext localContext)
    {
       if (localContext == null)
       {
           throw new ArgumentNullException("localContext");
       }
       // TODO: Implement your custom Plug-in business logic.
    }
  11. The first thing you will do is to get the plugin context, CRMService instance and TracingService instance using localContext passed to the function. All these objects are defined in the built in plugin.cs class.
    IPluginExecutionContext context = localContext.PluginExecutionContext;
    IOrganizationService service = localContext.OrganizationService;
    //ITracingService tracingService = localContext.TracingService;
  12. Here is code. It will check if the “account number” is null or empty and  create a task for a user to enter the account number.
    protected void ExecutePostAccountCreate(LocalPluginContext localContext)
    {
        if (localContext == null)
        {
            throw new ArgumentNullException("localContext");
        }
    
        // TODO: Implement your custom Plug-in business logic.
        // Obtain the execution context from the service provider.
        IPluginExecutionContext context = localContext.PluginExecutionContext;
        IOrganizationService service = localContext.OrganizationService;
        //ITracingService tracingService = localContext.TracingService;
    
    
        // 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"];
                    
            //EntityReference pp = entity.GetAttributeValue("primarycontactid");
            //tracingService.Trace(pp.LogicalName);
                   
                    
            try
            {
                //check if the account number exist
    
                if (entity.Attributes.Contains("accountnumber") == 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");
                            
                    // Create the task in Microsoft Dynamics CRM.
                    service.Create(task);
    
    
                }
            }
    
            catch (FaultException ex)
            {
                throw new InvalidPluginExecutionException("An error occurred in the plug-in.", ex);
            }
    
        }
    
    }
    I also left few commented lines in the code to show “How to use tracingservice to write in trace log”. You will able to see the trace only if there is an error in the plugin.
  13. Now right click on CRM Package project we created in step 2 and select deploy. It will register the plugin assembly as well as step for the plugin. Click on CRM Explorer to check the deployed plugin as shown in the following screen shot.pn1
  14. Create a new account and test the plugin.