Thursday, February 24, 2011

Plugin Registration Error: A proxy type with the name account has been defined by another assembly

So I ran into a very tricky error when building a custom tool to register CRM 2011 Plug-ins.  I wouldn't be surprised if other people run into the same issue when registering plug-ins programmatically. And its such a strange problem I thought it deserved an explanation.

Here is the exception I got when retrieving a list of records from CRM:
A proxy type with the name account has been defined by another assembly. Current type: Plugins.Sdk.Account, Plugins, Version=, Culture=neutral, PublicKeyToken=0b5679ac811dc738, Existing type: CrmSdk.Account, PluginRegisterTool, Version=, Culture=neutral, PublicKeyToken=null
Parameter name: account
In this case I was retrieving a list of PluginAssembly records, but the same exception happens when I try to retrieve ANY kind of entity.  Also note that "Plugins.Sdk.Account, Plugins" is a type in the plug-in assembly that I'm trying to register, and "CrmSdk.Account, PluginRegistrationTool" is the type in the application that's actually doing the registration.

A look at the stack trace also gives us a hint about what's really happening here:
Server stack trace:
   at Microsoft.Xrm.Sdk.AppDomainBasedKnownProxyTypesProvider.AddTypeMapping(Assembly assembly, Type type, String proxyName)
   at Microsoft.Xrm.Sdk.KnownProxyTypesProvider.LoadKnownTypes(Assembly assembly)
   at Microsoft.Xrm.Sdk.KnownProxyTypesProvider.RegisterAssembly(Assembly assembly)
   at Microsoft.Xrm.Sdk.KnownProxyTypesProvider.InitializeLoadedAssemblies()
   at Microsoft.Xrm.Sdk.AppDomainBasedKnownProxyTypesProvider..ctor()

So what's really happening here?

Sunday, February 13, 2011

CRM 2011 plug-in tips and tricks (part 2) - Testing plug-ins

Testing CRM plug-ins is now much easier than it was in previous version of CRM.   I will often create a simple console application that executes the plug-in I'm developing, just so I can make sure the core functionality of the plug-in works before I ever have to deploy it to the CRM server.  The same techniques can also be used for writing unit tests for your plug-ins.  

To create a simple test harness for your plug-ins you just need to create a few classes that implement the IServiceProvider, IOranizationServiceFactory, and IPluginExecutionContext interfaces. 

First is the TestServiceProvider Class.  This class is responsible for providing the plugin execution context and service factory to the plug-in.

public class TestServiceProvider : IServiceProvider
    private TestPluginContext _pluginContext;
    public TestServiceProvider(TestPluginContext pluginContext)
        _pluginContext = pluginContext;

    public object GetService(Type serviceType)
        if (serviceType == typeof(IPluginExecutionContext))
            return _pluginContext;
        if (serviceType == typeof(IOrganizationServiceFactory))
            return new TestServiceFactory();
        return null;

Saturday, February 12, 2011

CRM 2011 plug-in tips and tricks (part 1) - Develop and Debug in Sandbox Isolation Mode

There are a lot of examples of writing CRM 2011 plug-ins in the SDK, but none of them really describe the process of testing, troubleshooting, and properly debugging you're plug-in code.  As a result I see a lot of developers wasting time and making guesses at the reasons for their plug-in errors. So in the following posts I will outline some of the gotchas and tricks I've learned so far while developing plug-ins for CRM 2011.

#1.  Develop and Debug in Sandbox Isolation Mode (its faster)

If you ever want your plug-ins to work on CRM Online then you need to make sure you're plug-ins work in sandbox isolation mode.  And you will be surprised to learn what works and doesnt work when in sandbox mode.  These are just a few of the things I've run into that don't work in sandboxed plug-ins
The best way to avoid being surprised by any of these issues is to make sure you do all development in testing in Sandbox mode.  You don't want to be surprised when you deploy your plug-in to CRM Online and find out you're using some .NET function that isn't supported.

Also, it is now actually easier to debug plug-ins when they are sand-boxed. When registering a plug-in, you have three options of where the plug-in can be stored.
  1. On Disk - The plug-in assembly is stored on the CRM server file system (in the Server\Bin\Assembly folder). 
  2. Database - The plug-in assembly is actually uploaded to the CRM server and stored in the CRM database.
  3. GAC - The plug-in is stored in the global assembly cache on the CRM server.