What is the difference between IOrganizationService and OrganizationServiceProxy in Dynamics CRM?
Is it related to accessing services in Crm context and outside Crm Context?
What is the difference between IOrganizationService and OrganizationServiceProxy in Dynamics CRM?
Is it related to accessing services in Crm context and outside Crm Context?
Simplest answer is IOrganizationService is an interface whereas OrganizationServiceProxy is a class which implements the IOrganizationService interface. This means any properties/methods on IOrganizationService are by default also available via OrganizationServiceProxy.
If running in the context of a plugin or custom workflow activity it will give you access to an IOrganizationService that you can use to interrogate CRM.
If you are writing something external, such as a windows service or standalone application, then you generally use the class OrganizationServiceProxy to set up a connection to the CRM web service. You can obviously assign this to an IOrganizationService later (e.g. dependency injection / for unit testing purposes). Or if you prefer there is no reason why you can continue to use the OrganizationServiceProxy.
The IOrganisationService is used within plugins and custom workflow activities and derived from the execution context.
While the OrganisationServiceProxy is mainly used for code running outside the Dynamics CRM application.
If you're using the sdk assemblies (specifically microsoft.xrm.sdk.dll), then you'll be using an implementation of IOrganizationService, and the call time will be identical. The main purpose of OrganizationServiceProxy is to provide options for establishing a connection to CRM in code that runs outside of CRM .The OrganizationServiceProxy class implements the IOrganizationService and provides an authenticated WCF channel to the organization service
OrganizationService
is a higher level class that provides richer client side functionality and actually uses OrganizationServiceProxy
inside it.
The Microsoft.Xrm.Client assembly that holds this higher level API cannot be used in Plugins etc but is intended for rich clients and ASP.NET.
It's worth noting that the Microsoft.Xrm.Client assembly has been removed from the CRM2016 SDK. For 2016 projects you might consider using the XRM Toolking assemblies.
See msdn.microsoft.com/.../dn689057.aspx
It has similar functionality that you mention around the connection manager -msdn.microsoft.com/.../mt608573.aspx
OrganizationServiceProxy is implementation of IOrganizationService. It is similar to case as List is implementation of interface IList. If to speak about why on Earth Microsoft provides both interface and implementation besides testing, I can propose one interesting case which happened in my life. I was in need of re-reading information from dynamics crm. In my case OrganizationServiceProxy got expired faster, then information was received from CRM. In order to fix it I've created following facade:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
namespace OrganizationService
{
public delegate IOrganizationService CreateOrganizationServiceFunc(string organizationServiceUrl, string userName, string password, TimeSpan? timeout = null, bool useSSL = false);
public class OrganizationServiceFacade : IOrganizationService
{
private IOrganizationService _serviceInternal { get; set; }
private CreateOrganizationServiceFunc _creator;
Func<IOrganizationService> _orgServiceFactory;
public OrganizationServiceFacade(Func<IOrganizationService> orgServiceFactory)
{
_orgServiceFactory = orgServiceFactory;
CreateService();
}
private void CreateService()
{
_serviceInternal = _orgServiceFactory();
}
public void Associate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
{
try
{
_serviceInternal.Associate(entityName, entityId, relationship, relatedEntities);
}
catch (System.ServiceModel.Security.MessageSecurityException mex)
{
CreateService();
_serviceInternal.Associate(entityName, entityId, relationship, relatedEntities);
}
}
public Guid Create(Entity entity)
{
Guid result;
try
{
result = _serviceInternal.Create(entity);
}
catch (System.ServiceModel.Security.MessageSecurityException mex)
{
CreateService();
result = _serviceInternal.Create(entity);
}
return result;
}
public void Delete(string entityName, Guid id)
{
try
{
_serviceInternal.Delete(entityName, id);
}
catch (System.ServiceModel.Security.MessageSecurityException mex)
{
CreateService();
_serviceInternal.Delete(entityName, id);
}
}
public void Disassociate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
{
try
{
_serviceInternal.Disassociate(entityName, entityId, relationship, relatedEntities);
}
catch (System.ServiceModel.Security.MessageSecurityException mex)
{
CreateService();
_serviceInternal.Disassociate(entityName, entityId, relationship, relatedEntities);
}
}
public OrganizationResponse Execute(OrganizationRequest request)
{
try
{
return _serviceInternal.Execute(request);
}
catch (System.ServiceModel.Security.MessageSecurityException mex)
{
CreateService();
return _serviceInternal.Execute(request);
}
}
public Entity Retrieve(string entityName, Guid id, ColumnSet columnSet)
{
try
{
return _serviceInternal.Retrieve(entityName, id, columnSet);
}
catch (System.ServiceModel.Security.MessageSecurityException mex)
{
CreateService();
return _serviceInternal.Retrieve(entityName, id, columnSet);
}
}
public EntityCollection RetrieveMultiple(QueryBase query)
{
try
{
return _serviceInternal.RetrieveMultiple(query);
}
catch (System.ServiceModel.Security.MessageSecurityException mex)
{
CreateService();
return _serviceInternal.RetrieveMultiple(query);
}
}
public void Update(Entity entity)
{
try
{
_serviceInternal.Update(entity);
}
catch (System.ServiceModel.Security.MessageSecurityException mex)
{
CreateService();
_serviceInternal.Update(entity);
}
}
}
}
and then I've got simple reconnect mechanism:
Trace.TraceInformation("Creation of CRM connection");
for (var maxTry = 0; maxTry < reconectionTries; maxTry++)
{
try
{
var service = new OrganizationServiceFacade(() =>
XrmServiceCreator.CreateOrganizationService("organizationServiceUrl",
"username",
"userpassword",
DefaultTimeout));
var response = (WhoAmIResponse) service.Execute(new WhoAmIRequest());
if (response.Results.Count == 0)
{
throw new InvalidDataException($"CRM returned no data in response. Number of retries is: {maxTry}, user name: {ConfigSettings.Default.RunAsUser}, Default timeout = {DefaultTimeout}");
}
return service;
}
catch (Exception e)
{
Trace.TraceError("Exception: {0}", e);
}
}
method XrmServiceCreator.CreateOrganizationService returns instance of IOrganizationService, and behind curtains it creates instance of OrganizationServiceProxy