Tip #798: CrmServiceClient and multiple instances

Reduce reuse recycleIf you are using Microsoft.Xrm.Tooling.Connector.CrmServiceClient and relying on nuget to reference the assembly in your project (as you should) then you need to be aware of what seems to be an odd behavior but is, in fact, a bug fix.

Run the following code:

var s1 = $@"Url=https://foobar.crm.dynamics.com;
   AuthType=Office365;
   UserName=user@foobar.onmicrosoft.com;
   Password=password";
var s2 = $@"Url=https://barbaz.crm.dynamics.com;
   AuthType=Office365;
   UserName=user@barbaz.onmicrosoft.com;
   Password=password";

using (var crmSvc = new CrmServiceClient(s1))
{
  Console.WriteLine($"Ready={crmSvc.IsReady}");
  Console.WriteLine($"User={crmSvc.GetMyCrmUserId()}");
  Console.WriteLine(
    $"Org={crmSvc.ConnectedOrgFriendlyName}");
}
using (var crmSvc = new CrmServiceClient(s2))
{
  Console.WriteLine($"Ready={crmSvc.IsReady}");
  Console.WriteLine($"User={crmSvc.GetMyCrmUserId()}");
  Console.WriteLine(
    $"Org={crmSvc.ConnectedOrgFriendlyName}");
}

And get:

Ready=True
User=8fa1eeae-dead-beef-dead-b6b5240774e4
Org=Foobar
Ready=True
User=8fa1eeae-dead-beef-dead-b6b5240774e4
Org=Foobar

Wait a minute, what? Same user and org? Despite the use of the disposable object, connection didn’t change at all?!

Yes, this is correct and, if you were relying on similar code before, you were riding on top of the unintended buggy behavior. Correct and documented behavior is for the connection to be cached and reused unless you specify RequireNewInstance flag either as part of the connection string:

var s2 = $@"RequireNewInstance=True;
  Url=https://barbaz.crm.dynamics.com;
  AuthType=Office365;
  UserName=user@barbaz.onmicrosoft.com;
  Password=password";

or as part of a constructor (useUniqueInstance parameter):

CrmServiceClient crmSvc = new CrmServiceClient(
    "user@barbaz.onmicrosoft.com",
    CrmServiceClient.MakeSecureString("password"),
    "NorthAmerica", "barbaz", 
    useUniqueInstance: true,
    useSsl: true, isOffice365: true);

The change is reflected in the notes on nuget package, along with a list of other fixes and updates:

RequireNewInstance=True will now properly create a unique connection instance, RequireNewInstance=false, will now properly reuse the cached instance of the connection, default is ‘false’

If you are connecting to more than one instance in your code or, if you’d like to maintain two separate connections with the separate instances of metadata, cache, etc, make sure that you use this flag.

Tweet about this on TwitterShare on Facebook2Share on Google+0

3 thoughts on “Tip #798: CrmServiceClient and multiple instances

  1. Steven Rasmussen says:

    Thanks! This just saved my bacon!

  2. MarcosB says:

    The caching behavior implemented in the last SDK was a bad idea. Microsoft documentation on this issue doesn’t help either.

    I found another bug. If you want to test a crm online connection string for example, creating a CrmServiceClient instance.

    you do the first test using a connection string
    “RequireNewInstance=True; Url=https://myCompany.crm.dynamics.com; Username=myUser@myCompany.onmicrosoft.com; Password=myPassowrd; AuthType=Office365”

    Then you use another wrong connections string, with a url that doesn’t exists:
    “RequireNewInstance=True; Url=https://xxx.crm.dynamics.com; Username=myUser@myCompany.onmicrosoft.com; Password=myPassowrd; AuthType=Office365”
    The CrmServiceClient keeps using the first connection string, so you cannot determine if the new connection string is correct (the only option would be to unload the app domain and try again which is not convenient in an asp.net application :\ )

Leave a Reply

Your email address will not be published. Required fields are marked *