Improving Dynamics CRM connection performance with Singleton pattern

Calling Dynamics CRM services is slow process.The authentication process adds the most overhead in establishing a connection to CRM. The call needs to go through multiple steps in order to be authenticated and authorized to access the data in Dynamics CRM.

If you have an application that needs to perform CRUD operation outside of CRM you can leave the connection open to Dynamics CRM with Singleton pattern.

Singleton pattern:

public class XrmConnectionProvider
    {
        private static IOrganizationService instance;
        private static object _lockObject = new object();

		private static IConfigurationService _configurationService;
        
		private XrmConnectionProvider() { }
		
        public static IOrganizationService CRMService
        {
            get
            {
                try
                {
                    lock (_lockObject)
                    {
                        if (instance == null)
                        {
							var container = IoC.Initialize();
							_configurationService = container.GetInstance<IConfigurationService>();


                            instance = Connect();
                        }
                        return instance;
                    }
                }
                catch (Exception ex)
                {
					throw new Exception("Unable to connect to CRM", ex);
                }

            }
        }
        private static IOrganizationService Connect()
        {
		     //user name and password stored in a config file
			var config = _configurationService.Get<XrmClientConfiguration>();

			Uri dInfo = new Uri(config.XrmUri);
			ClientCredentials clientcred = new ClientCredentials();
			clientcred.UserName.UserName = config.XrmClientCredUserName;
			clientcred.UserName.Password = config.XrmClientCredPassword;


			#region on-premise/online

			DiscoveryServiceProxy dsp = new DiscoveryServiceProxy(dInfo, null, clientcred, null);
            dsp.Authenticate();
            RetrieveOrganizationsRequest rosreq = new Microsoft.Xrm.Sdk.Discovery.RetrieveOrganizationsRequest();
            RetrieveOrganizationsResponse r = (RetrieveOrganizationsResponse)dsp.Execute(rosreq);

            //get the OrganizationService
            OrganizationServiceProxy _serviceproxy = new OrganizationServiceProxy(new Uri(config.XrmOrgServiceProxy), null, clientcred, null);
            //In order to use the generated types when dealing with the organization service, you have to add the ProxyTypesBehavior to the endpoint Behaviors collection. This instructs the OrganizationServiceProxy to look in the assembly for classes with certain attributes to use. The generated classes are already attributed with these attributes. Simply, this makes all interactions with the organization service to be done using the generated typed classes for each entity instead of the generic Entity class we used earlier.
            _serviceproxy.ServiceConfiguration.CurrentServiceEndpoint.EndpointBehaviors.Add(new ProxyTypesBehavior());
            //Do not forget to include _serviceproxy.EnableProxyTypes();. Without this line,you will be unable to use early binding.
            _serviceproxy.EnableProxyTypes();
            IOrganizationService service = (IOrganizationService)_serviceproxy;

            #endregion
            return service;
        }
    }

Now in your code you can call below class and it will only generate one instance instead of calling it for each request :

 var CRMService= XrmConnectionProvider.Connect();

Here is the result of URL based test on Visual studio online after applying above approach :

The test ran for duration of 120 seconds with 25 users load hitting my Web API application (hosted on azure) retrieving Dynamics CRM contacts.

Before:

url-based-test-dynamics-crm-before

After:

url-based-test-dynamics-crm-after

 

The only caveat to this method is that you need to monitor your token expiry depending on your implementation method and renew it before expiry.
You can read about it on this blog post.
But before that you need to increase the life time of token if you’ve configured your CRM for IFD.  By default the ADFS token last for 60 minutes. By using Windows PowerShell, you can change the TokenLifetime property for the relying party objects that you created from 60 minutes to a longer period, such as 480 minutes (8 hours).

From MSDN best practices:

Monitor your WCF security token (Token) and refresh it before it expires so that you do not lose the token and have to start over with authentication. To check the token, create a custom class that inherits from the OrganizationServiceProxy or DiscoveryServiceProxy class and that implements the business logic to check the token. Or wrap the proxy classes in a new class. Another technique is to explicitly check the token before each call to the web service. Example code that demonstrates these techniques can be found in the ManagedTokenDiscoveryServiceProxy, ManagedTokenOrganizationServiceProxy, and AutoRefreshSecurityToken classes in the Helper code: ServerConnection class topic.

Advertisements

One thought on “Improving Dynamics CRM connection performance with Singleton pattern

  1. Pingback: Refresh Security Token for Microsoft Dynamics CRM | Ali Sharifi's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s