When looking at Plugins in CRM 2011, it is important to break this post down into two separate sections – with a link to a follow-up third section linking to a separate post on this blog detailing how to incorporate LINQ into 2011 Plugins.
Compiling the Plugin Registration Tool ready for use with CRM 2011
Developing and Registering a new CRM 2011 Plugin
Using LINQ in CRM 2011 Plugins
Compiling the Plugin Registration Tool ready for use with CRM 2011
As with previous versions of Dynamics CRM, CRM 2011 requires the next generation of development tools to start developing and registering Plugins – so we have a few pre-requisites to take care of first:
(1) First of all you will need the .NET 4 Framework installed on your development environment, you can download this from this from here.
(2) Second we will need Visual Studio 2010 on your development environment – as this is required to open and compile the Plugin Registration Tool code that is included in the CRM 2011 SDK.
(3) Thirdly we will need the Microsoft.IdentityModel reference available to your development environment to successfully compile and run the Plugin Registration Tool – this can be done via downloading and installing the Windows Identity Foundation package from the following link.
These three steps should setup your development environment to open, compile and run the Plugin Registration Tool Solution within the CRM 2011 SDK.
Running the Plugin Registration Tool then brings up the familiar interface for adding a new Connection to a MSCRM Deployment – in my case for this post I am using a connection to a hosted instance of the CRM 2011 Beta, and so need to supply my Hosted URL and Microsoft Passport credentials to then connect to CRM.

Running the CRM 2011 Plugin Registration Tool and creating a Connection to either a Hosted or On-Premise deployment of CRM 2011 Beta
I have seen a few problems around this where the ‘An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.’ error is encountered after specifying your CRM 2011 details – the following step can work to resolve this problem:
Look into your User Profile directory (C:\Users\[your user account name] in Windows 7), browse to a folder titled ‘LiveDeviceID’ and delete the LiveDevice.xml file contained within this folder. This removes any cached credentials from your workstation which may be blocking the connection between the Plugin Registration Tool and the hosted CRM 2011 Service.
Thanks to the contributors on the thread, really helped me out when hitting this error.
Once connected to our deployment of CRM 2011 – we can look at the list of Registered Plugins that we have in this deployment. Here we have the option to Register new Assemblies, Steps, Images and Service End-Points into our deployment of CRM 2011. Assemblies, Steps and Images should be familiar territory to anyone involved with CRM 4, Service End-Points are a new addition for CRM 2011 and may well form the topic of a future post, however for the moment we will be looking at registering a new Assembly to insert a simple piece of Plugin logic into CRM.
To do this our first step is to compile a Plugin Assembly for CRM 2011 – simplest way to do this initially is to again look into the CRM 2011 SDK and open one of the provided example solutions in Visual Studio 2010. The solution found at ‘.\sdk\samplecode\cs\plug-ins’ in the SDK is a good starting point:
This solution should be ready to go and so should compile into a DLL that we can then use the Plugin Registration Tool to register into CRM 2011.
Notice here we have a new option for deciding to upload the Assembly in a Sandbox mode or not – the CRM SDK contains further details on the difference between using the Sandbox or None setting here.
As with CRM 4, this will register the assembly and number of Plugins for use in CRM 2011 but not register where or when to execute these Plugins – for this we need to register a Step off the Plugin. One of the Plugins in this example solution is a simple Account Autonumber which for the code to make sense would require registration against the Account Pre-Create Event to make sense:

Registering a new Step within CRM 2011 to invoke the example Account Number Plugin provided in the CRM 2011 SDK
The options here for registering a new Step are similar to CRM 4 with a few tweaks and differences that could form the topics of future posts.
Once registered, the list of Plugins and Steps should then resemble the following:
With the Plugin and Step registered, we should be able to browse into CRM 2011 and test that the Plugin Logic is now in effect.
As this is a simple Autonumber Plugin on the Account entity – we can add a new Account in CRM and check that the Account Number field is now being populated automatically:

The result in CRM 2011 as a result of the Plugin being registered on the Create Step of the Account Entity
And we can see the Plugin in affect in CRM 2011 as a result of compiling and running the Plugin Registration Tool – obviously there is a variety of new options available within the Tool for CRM 2011, but otherwise the process is similar to CRM 4. Our next step in this post is to look into how we can develop a custom Plugin for CRM 2011 that we can then register and see the affect of.
Developing and Registering a new CRM 2011 Plugin
Plugins for CRM 4 took a great idea in Callouts for CRM 3 and improved the concept immensely by allowing code to be uploaded into the Database via the Plugin Registration Tool, removing the need for saving DLL files to disk and editing XML Config files that drove Callouts. The ability to upload managed code to a remote hosted or on-premise installation of Dynamics CRM that would then fire on a specific entity event gave developers and solution architects a huge range of business logic and integration options.
Which goes some way to explain ‘not broke, don’t fix’ approach to Plugins in CRM 2011. The approach to coding and registering a Plugin is very similar in terms of Target Messages (the XML update that is happening to a record) and Pre/Post Images (the XML details describing the record before the update and after the update.
Obviously the ability to then amend other records through the CRM Webservice/API is different and involves a learning curve (particularly the LINQ approach, althrough we have seen this previously in latter releases of the CRM 4 SDK) but the underlying development patterns for Plugin Execution and Message Pipeline should be familiar to anyone used to developing Plugins against CRM 4.
If we take an example piece of business logic that we may want to implement for a client, say a simple integer field counting the number of Opportunities that have been recorded for a Customer Account, the following steps give an idea of how we could achieve this in CRM 2011:
(1) Create a new Visual Studio 2010 Class Library Project, on the assumption we are not using a Plugin Template Project.
(2) Add the required references from the CRM 2011 SDK.
Microsoft.CRM.SDK.Proxy
Microsoft.XRM.SDK
(3) Add a final required reference from the .NET Framework
System.ServiceModel
System.Runtime.Serialization
(4) In much the same fashion as CRM 4, our Plugin Assembly must be signed with a Strong Key to be deployed into a CRM 2011 Deployment.
(5) With these steps done we can add a new Class Library code file for our Plugin in a similar fashion to CRM 4, with a few notable differences:
The class we develop in the Plugin inherits from IPlugin interface within the SDK
public class MyPluginName : IPlugin
This then allows us to implement a single Execute method which, as per CRM 4, is the central Main() function that the Plugin executes as part of the CRM Message Pipeline.
public void Execute(IServiceProvider serviceProvider)
This takes in the servceProvider object that contains the incoming details about CRM that come from the CRM Message Pipeline – from this we can derive the Plugin Execution Context that we are familiar with from CRM 4.
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
From the Plugin Execution Context, we can read back the Target Message, PreMessage Images or PostMessage Images in the usual fashion as CRM 4.
if (context.PostEntityImages.Contains("PostImage") &&
context.PostEntityImages["PostImage"] is Entity)
{
postMessageImage = (Entity)context.PostEntityImages["PostImage"];
}
else
{
throw new Exception("No Post Image Entity in Plugin Context for Message");
}
if (context.PreEntityImages.Contains("PreImage") &&
context.PreEntityImages["PreImage"] is Entity)
{
preMessageImage = (Entity)context.PreEntityImages["PreImage"];
}
else
{
throw new Exception("No Pre Image Entity in Plugin Context for Message");
}
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
targetMessageImage = (Entity) context.InputParameters["Target"];
}
else
{
throw new Exception("No Target Message Entity in Plugin Context for Message");
}
As per CRM 4, we can also use the Plugin Execution Context to obtain a limited reference to the CRM Webservice such that we can make Retrieve, Create or Update requests to CRM – the code here is slightly different from CRM 4 but the concept is similar:
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = factory.CreateOrganizationService(context.UserId);
Beyond these points, the process of developing a Plugin for CRM 2011 can then use the same structure as CRM 4 – the most notably change being the underlying changes to how Webservice Requests are communicated to the CRM Webservice, however these are documented or in the process of being documented in the CRM 2011 SDK and may well form the subject of a further post on CRM 2011. An obvious change in the code below is the concept of the EntityReference property instead of CRM 4′s Lookup, Owner or Customer property types.
The following table is a brief breakdown of how this changes reading back Lookup properties from a Plugin Image:
| CRM 4 | CRM 2011 |
Microsoft.Crm.Sdk.Key opportunityid = (Microsoft.Crm.Sdk.Key) postImage.Properties["opportunityid"]; Guid opportunityRecordId = opportunityid.Value; |
EntityReference opportunityid = (EntityReference) postImage.Attributes["opportunityid"]; Guid opportunityRecordId = opportunityid.Id; |
Microsoft.Crm.Sdk.Customer customerid = (Microsoft.Crm.Sdk.Customer)postImage.Properties["customerid"]; string customerRecordType = customerid.type; Guid customerRecordId = customerid.Value; |
EntityReference customerid = (EntityReference) postImage.Attributes["customerid"]; string customerRecordType = customerid.Type; Guid customerRecordId = customerid.Id; |
(6) From these points we can develop our Plugin Logic to work from within CRM 2011 – the following code describes a very basic Plugin to count Opportunities that are linked to an Account.
using System;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
public class OpportunityCountPlugin : IPlugin
{
const string OPPORTUNITYCOUNT_DATABASENAME = "new_opportunitycount";
public void Execute(IServiceProvider serviceProvider)
{
try
{
// Obtain the execution context from the service provider.
IPluginExecutionContext context =
(IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
Entity opportunityEntityImage;
#region Get Opportunity Entity Image
if (context.MessageName == "Create")
{
// use Post Image for Create Messages
if (context.PostEntityImages.Contains("PostImage") &&
context.PostEntityImages["PostImage"] is Entity)
{
opportunityEntityImage = (Entity)context.PostEntityImages["PostImage"];
}
else
{
throw new Exception("No Post Image Entity in Plugin Context for Create Message");
}
}
else if (context.MessageName == "Delete")
{
// use Pre Image for Delete Messages
if (context.PreEntityImages.Contains("PreImage") &&
context.PreEntityImages["PreImage"] is Entity)
{
opportunityEntityImage = (Entity)context.PreEntityImages["PreImage"];
}
else
{
throw new Exception("No Pre Image Entity in Plugin Context for Delete Message");
}
}
else
{
// Plugin not valid for any other Message Types
throw new Exception("OpportunityCountPlugin Plugin is not valid for the '" + context.MessageName + "' message type");
}
if (opportunityEntityImage.LogicalName != "opportunity")
{
// plugin is valid for this entity
throw new Exception("OpportunityCountPlugin Plugin is not valid for the '" + opportunityEntityImage.LogicalName + "' entity type");
}
#endregion
#region Plugin Business Logic
// interrogate Opportunity Post Image XML to determine the 'customerid' field
if (opportunityEntityImage.Attributes.Contains("customerid"))
{
EntityReference customerid = (EntityReference)opportunityEntityImage.Attributes["customerid"];
if ((customerid.LogicalName == "account") && (!( customerid.Id.Equals(Guid.Empty) )))
{
// Get a reference to the Organization service.
IOrganizationServiceFactory factory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
// Local variable for reference to CRM Service - as Plugins should be developed as stateless
// due to CRM 2011 Caching Plugin object instances
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
int opportunities = GetOpportunityCount(customerid.Id, service);
UpdateOpportunityCount(customerid.Id, opportunities, service);
}
}
#endregion
}
catch (Exception ex)
{
// Handle general exception
throw new InvalidPluginExecutionException("CRM2011.Example.OpportunityCountPlugin --> Execute '" + ex.Message + "'");
}
}
#region Plugin CRM Methods
/// <summary>
/// Returns a simple count of the number of Opportunities associated to an Account
/// </summary>
/// <param name="accountId">The GUID Id of the Account involved</param>
/// <param name="service">The CRM 2011 Organization Service reference to retrieve the data from</param>
/// <returns>The current number of Opportunities associated directly with the Account</returns>
public int GetOpportunityCount(Guid accountId, IOrganizationService service)
{
try
{
QueryByAttribute queryByAttribute = new QueryByAttribute("opportunity");
queryByAttribute.ColumnSet = new ColumnSet(new string[] { "opportunityid" });
queryByAttribute.Attributes.Add("customerid");
queryByAttribute.Values.Add(accountId);
EntityCollection retrieved = service.RetrieveMultiple(queryByAttribute);
return retrieved.Entities.Count;
}
catch (FaultException<OrganizationServiceFault> exceptionServiceCall)
{
throw new Exception("GetOpportunityCount [OrganizationServiceFault '" + exceptionServiceCall.Message + "']");
}
catch (Exception ex)
{
throw new Exception("GetOpportunityCount [GeneralException '" + ex.Message + "']");
}
}
/// <summary>
/// Updates a custom Opportunity Count field on the specified Account to a new integer value
/// </summary>
/// <param name="accountId">The GUID Id of the Account involved</param>
/// <param name="opportunityCount">The new integer value to update the Opportunity Count field to</param>
/// <param name="service">The CRM 2011 Organization Service reference to update to</param>
public void UpdateOpportunityCount(Guid accountId, int opportunityCount, IOrganizationService service)
{
try
{
Entity updateAccount = new Entity("account");
updateAccount.Attributes.Add("accountid", accountId);
updateAccount.Attributes.Add(OPPORTUNITYCOUNT_DATABASENAME, opportunityCount);
service.Update(updateAccount);
}
catch (FaultException<OrganizationServiceFault> exceptionServiceCall)
{
throw new Exception("UpdateOpportunityCount [OrganizationServiceFault '" + exceptionServiceCall.Message + "']");
}
catch (Exception ex)
{
throw new Exception("UpdateOpportunityCount [GeneralException '" + ex.Message + "']");
}
}
#endregion
}
(7) With the code developed and compiled we can then register the Plugin into our deployment of CRM 2011 (currently Beta) to insert the developed Business Logic. In the simple Opportunity Count example above, this would mean registering the Plugin on Create or Delete of the Opportunity entity with associated Post or Pre Image.
(8) With this done we should be able to see the Plugin in action – this Plugin fires whenever we delete or create an Opportunity that is attached to an Account, so we can add several Opportunities to a particular Account as way of seeing the ‘new_opportunitycount’ field update accordingly:
Obviously this Plugin in itself is slightly flawed as the logic does not account for Opportunities that have a Contact linked as the Customer, and realistically a Report or Chart would be better placed to show a running tally of Opportunities per Account. However hopefully this gives an initial example of how developing a Plugin for CRM 2011 may differ from Plugins in CRM 4.
From experience of CRM 3 and 4 Projects Plugins and Callouts are often the most popular method for advanced customisation of Dynamics CRM as, whilst firmly in the Development camp as opposed to Functional Customisation, Plugins can be simply developed and deployed as re-usable components into any CRM deployment that meets the Plugin dependencies for fields and entities.
For adding LINQ Queries into CRM 2011 Plugins, the following post acts as a follow-up and may be helpful: Using LINQ in CRM 2011 Plugins









Pingback: CRM 2011 | CRM Consultancy Blog
Pingback: Tweets that mention Plugins in CRM 2011 | CRM Consultancy Blog -- Topsy.com
Pingback: Did you know, Dynamics CRM & xRM #5 « North 52
I got an error trying to connect PluginRegistration to my CRM OnLine ans I found the solution in your article. Thank you very much for your help.
Pingback: Overview CRM 2011 | Onestopdynamics
Thanks for the article, it was great, a part of the code for obtaining the the count of the opportunities linked to the account is missing.
Very useful. Thanks for sharing.
I have created a plugin registration tool that runs from a command line for Microsoft Dynamics CRM 2011 here: http://pluginregcrm2011.codeplex.com/
Since this post was originally published, a new page has been added to the CRM SDK which might be useful when compiling and using the Plugin Registration Tool:
http://msdn.microsoft.com/en-us/library/hh237515.aspx
Pingback: CRM 4 – Workflows, Custom Workflows ou Plugins | Tiago Michelini Cardoso
Pingback: CRM2011 Plugins, Pre-image and post-image -Kevin's Mocha
Pingback: CRM 2011 Online Plugin Registration Tool Connection Error | shoaibfaruq
do you guys know anything about vs 2010 template for dynamics crm plugin?
There is constructor: internal Plugin(Type childClassName)
{
this.ChildClassName = childClassName.ToString();
}
How this get called? when childClassName gets passed?
thanks,
Thanks for the post ! This was a good starting point for me !
Very Good. Helped me a lot. Thanks
very useful information thanks