When CRM 2011 got released one of the things I was really excited about was CrmSvcUtil to generate Early Bound Entity Classes. In CRM 4 this option was sorely lacking and I ended up creating a custom tool to create my own wrapper classes. However, I prefer to let Microsoft do the hard work for me and was looking forward to using this tool.
If you follow the example in the CRM SDK you create a class project for your plugins and add the CrmSvcUtil generated class file to this project. To demonstrate the concept I’ll use a plugin that sets the correct casing for the first name, selects the first existing contact from the database and sets the job title of the new contact to the full name of the retrieved contact (the plugin is purely illustrational – I am not pretending to create a usable and/or logical plugin). The plugin is registered for the contact create.
- using System;
- using System.Linq;
- using Microsoft.Xrm.Sdk;
- namespace OG.Xrm.Plugins
- {
- public class ContactPlugin : IPlugin
- {
- public void Execute(IServiceProvider serviceProvider)
- {
- var context = (IPluginExecutionContext) serviceProvider.GetService(typeof (IPluginExecutionContext));
- var entity = (Entity) context.InputParameters["Target"];
- var contact = entity.ToEntity<Contact>();
- contact.FirstName = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(contact.FirstName);
- var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
- var service = serviceFactory.CreateOrganizationService(context.UserId);
- var organisationContext = new CrmContext(service);
- var contacts =
- from c in organisationContext.ContactSet
- select c;
- contact.JobTitle = contacts.First().FullName;
- }
- }
- }
At this point my plugin project contains two files: the contactplugin class and the CrmSvcUtil generated class.

After registering the ContactPlugin for the contact create everything works as expected: the first name casing gets changed and the job title gets set correctly.
So far so good you might say, but the problem with this scenario is it only works for small projects. If you are working on a large Xrm implementation changes are you want to break up your project into separate dlls. I also want to avoid having multiple copies of the CrmSvcUtil generated class in my projects. For instance, I might like to break my project up into the following dlls:
- OG.Xrm.Common – Containing the business logic and CrmSvcUtil generated model for my Xrm application referenced by all other dlls
- OG.Xrm.Plugins – for my plugins
- OG.XRM.WorkflowActivities – for custom workflow activities
- OG.Xrm.Web – for custom web pages that might be part of the project
- etc.
Now there are some challenges with creating your project like this. The most obvious one is that the CRM Solution Package does not allow you to include additional dlls that are referenced by your plugin assembly. There are various strategies to get around this problem and the “solution” Microsoft seems to be pushing the use ILMerge to merge your referenced dlls with your plugin dll. However, using ILMerge is a bit of a pain and (in my opinion) adds unnecessary complexity. If you are writing plugins for CRM Online this really is your only option, but in an on premise scenario you can deploy dlls referenced by your plugin assembly in the GAC.
Of course going down this path means you can’t rely on your CRM solution alone to deploy your full application: you’ll have to take care of deploying any additional dlls to the GAC. To me this is not a big problem as in my experience you usually end up with a number of artefacts that do not fit into the CRM solution anyway (for example console applications, aspx pages and custom WCF services). My preferred solution is to create a setup package that takes care of deploying all the bits and pieces that do not fit into the CRM solution and than deploys the CRM solution.
However, there is another challenge. If I rework my project and move the CrmSvcUtil model into a separate class project I’ll end up with this:

If I deploy the OG.Xrm.Common dll to the GAC, update the Plugin and try to create a contact I will receive the following error: “Object of type ‘Microsoft.Xrm.Sdk.Entity’ cannot be converted to type ‘OG.Xrm.Common.Contact’”

If you debug the code you’ll discover the error is thrown by the following line:
- contact.JobTitle = contacts.First().FullName;
Also notice how these lines execute without any problem: the problem only occurs once we start using the organizations service context class!
- var contact = entity.ToEntity<Contact>();
- contact.FirstName = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(contact.FirstName);
The problem seems to be that the OrganizationService that gets passed to organization service context class no longer recognizes the Early Bound Entity Classes in the separate dll. Luckily there is a (undocumented) solution for this problem: registering your Early Bound Entity Classes explicitly. To do this we have to change make the following changes in the OG.Xrm.Plugins project:
- Add the following references to the project (both dlls can be found in the C:\Program Files\Microsoft Dynamics CRM\Server\bin\folder):
- Microsoft.Crm.ObjectModel.dll
- Microsoft.Crm.Platform.Server.dll
- Add the highlighted line of code before getting calling the GetService method:
- ((IProxyTypesAssemblyProvider)context).ProxyTypesAssembly = typeof(Contact).Assembly;
- var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
- varservice = serviceFactory.CreateOrganizationService(context.UserId);
- var organisationContext = new CrmContext(service);
- varcontacts =
- from c inorganisationContext.ContactSet
- selectc;
- contact.JobTitle = contacts.First().FullName;
Update your plugin and try again and this time the plugin will complete successfully.
UPDATE 19/04/2011:
Changed ((Microsoft.Crm.Extensibility.PipelineExecutionContext)Context).ProxyTypesAssembly = typeof(TServiceContext).Assembly;
to
((IProxyTypesAssemblyProvider)Context).ProxyTypesAssembly = typeof(TServiceContext).Assembly;
The original line only works with synchronous plugins, but throws an exception for asynchronous plugins. Using the IProxyTypesAssemblyProvider interface works for both synchronous and asynchronous plugins.