Tuesday, 14 March 2017

MSCRM Plugin using early binding

1) Generate CRM proxy class using CSV UTIL using following config detail

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="url" value="https:///XRMServices/2011/Organization.svc"/>
    <add key="out" value="class.cs"/>
    <add key="namespace" value="MscrmOnlinePlugin"/>
    <add key="serviceContextName" value="XrmServiceContext"/>
    <add key="username" value="username"/>
    <add key="password" value="password "/>
  </appSettings>
</configuration>


2) Adding the generated proxy file in project

3) Create plugins.cs to project inheriting Iplugin interface

public class Plugins : IPlugin
 {
 protected class LocalPluginContext

 {
 internal IServiceProvider ServiceProvider

 {
 get;


private set;

 }
 internal IOrganizationService OrganizationService



 {
 get;


private set;
 }
 internal IPluginExecutionContext PluginExecutionContext

 {
 get;

private set;
 }
 internal ITracingService TracingService


 {
 get;
private set;

 }
 private LocalPluginContext()

 {
 }
 internal LocalPluginContext(IServiceProvider serviceProvider)

 {
 if (serviceProvider == null)

 {
 throw new ArgumentNullException("serviceProvider");

 }
 // Obtain the execution context service from the service provider.

this.PluginExecutionContext = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

// Obtain the tracing service from the service provider.

this.TracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

// Obtain the Organization Service factory service from the service provider
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
// Use the factory to generate the Organization Service.

this.OrganizationService = factory.CreateOrganizationService(this.PluginExecutionContext.UserId);

 }
 internal void Trace(string message)

 {
 if (string.IsNullOrWhiteSpace(message) || this.TracingService == null)

 {
 return;


 }
 if (this.PluginExecutionContext == null)

 {
 this.TracingService.Trace(message);

 }
 else

 {
 this.TracingService.Trace(

"{0}, Correlation Id: {1}, Initiating User: {2}",

 message,
 this.PluginExecutionContext.CorrelationId,

this.PluginExecutionContext.InitiatingUserId);

 }

 }

 }
 private Collection<Tuple<int, string, string, Action<LocalPluginContext>>> registeredEvents;

/// <summary>



/// Gets the List of events that the plug-in should fire for. Each List



/// Item is a <see cref="System.Tuple"/> containing the Pipeline Stage, Message and (optionally) the Primary Entity.



/// In addition, the fourth parameter provide the delegate to invoke on a matching registration.



/// </summary>



protected Collection<Tuple<int, string, string, Action<LocalPluginContext>>> RegisteredEvents

 {
 get


 {
 if (this.registeredEvents == null)

 {
 this.registeredEvents = new Collection<Tuple<int, string, string, Action<LocalPluginContext>>>();
 }
 return this.registeredEvents;

 }

 }
 /// <summary>

/// Gets or sets the name of the child class.



/// </summary>



/// <value>The name of the child class.</value>

protected string ChildClassName




 {
 get;


private set;

 }
 /// <summary>


/// Initializes a new instance of the <see cref="Plugin"/> class.

/// </summary>

/// <param name="childClassName">The <see cref=" cred="Type"/> of the derived class.</param>

internal Plugin(Type childClassName)

 {
 this.ChildClassName = childClassName.ToString();



 }
 /// <summary>



/// Executes the plug-in.



/// </summary>



/// <param name="serviceProvider">The service provider.</param>



/// <remarks>



/// For improved performance, Microsoft Dynamics CRM caches plug-in instances.



/// The plug-in's Execute method should be written to be stateless as the constructor



/// is not called for every invocation of the plug-in. Also, multiple system threads



/// could execute the plug-in at the same time. All per invocation state information



/// is stored in the context. This means that you should not use global variables in plug-ins.



/// </remarks>



public void Execute(IServiceProvider serviceProvider)


 {
 if (serviceProvider == null)

 {
 throw new ArgumentNullException("serviceProvider");
 }
 // Construct the Local plug-in context.


LocalPluginContext localcontext = new LocalPluginContext(serviceProvider);

localcontext.Trace(string.Format(CultureInfo.InvariantCulture, "Entered {0}.Execute()", this.ChildClassName));


try

 {
 // Iterate over all of the expected registered events to ensure that the plugin


// has been invoked by an expected event

// For any given plug-in event at an instance in time, we would expect at most 1 result to match.
Action<LocalPluginContext> entityAction =
 (from a in this.RegisteredEvents


where (

 a.Item1 == localcontext.PluginExecutionContext.Stage &&

 a.Item2 == localcontext.PluginExecutionContext.MessageName &&
 (string.IsNullOrWhiteSpace(a.Item3) ? true : a.Item3 == localcontext.PluginExecutionContext.PrimaryEntityName)
 )
 select a.Item4).FirstOrDefault();

if (entityAction != null)

 {
 localcontext.Trace(string.Format(


CultureInfo.InvariantCulture,


"{0} is firing for Entity: {1}, Message: {2}",


this.ChildClassName,


localcontext.PluginExecutionContext.PrimaryEntityName,

localcontext.PluginExecutionContext.MessageName));

entityAction.Invoke(localcontext);
 // now exit - if the derived plug-in has incorrectly registered overlapping event registrations,



// guard against multiple executions.



return;

 }

 }
 catch (FaultException<OrganizationServiceFault> e)


 {
 localcontext.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));


// Handle the exception.

throw;


 }
 finally


 {
 localcontext.Trace(string.Format(CultureInfo.InvariantCulture, "Exiting {0}.Execute()", this.ChildClassName));



 }

 }

 }
4) Create pluginsbase  abstract  class


public abstract class PluginsBase : IPlugin



 {
 public IPluginExecutionContext Context;


public IOrganizationServiceFactory Factory;


// public CrmOrganizationServiceContext CrmOrgService;



public XrmServiceContext ServiceContext;


public IOrganizationService _service;


protected abstract void OnExecute();


public void Execute(IServiceProvider serviceProvider)

 {
 // Obtain the execution context from the service provider.



 Context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));


//If ILMerged used for plug in , we can remove the below line of code



//InitiliazeEntityType(();

// Get a reference to the organization service.



 Factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));


// _service = (IOrganizationService)serviceProvider.GetService(typeof(IOrganizationService));



//CrmOrgService = new CrmOrganizationServiceContext(Factory.CreateOrganizationService(Context.UserId));



ServiceContext = new XrmServiceContext(Factory.CreateOrganizationService(Context.UserId));


OnExecute();

 }
 public PluginBase()


 {

 }

 }

 5)Add Account Update and create plugin code

public class AccountUpdate : PluginBase

 {
 protected override void OnExecute()



 {

 {
 Entity entity = (Entity)Context.InputParameters["Target"];

 if (entity.LogicalName != "account" )
return;
try
 {
 if (Context.MessageName.ToLower() == "create")
 {
 Guid parentAcc = new Guid("C3390F45-D5FF-E611-8116-C4346BDCFDE1");

 Account acc = entity.ToEntity<Account>();
  ServiceContext.ClearChanges();
 acc.WebSiteURL = "google@gmail.com";
 acc.ParentAccountId = new EntityReference(Account.EntityLogicalName, parentAcc); ;
 acc.Address1_AddressTypeCode = new OptionSetValue(1);

 }
 if (Context.MessageName.ToLower() == "update")

 {

 Guid parentAcc = new Guid("C3390F45-D5FF-E611-8116-C4346BDCFDE1");
 Account account = new Account();

 account.Id = entity.Id;

 account.LogicalName = entity.LogicalName;
 account["websiteurl"] = "google.com";
 account["parentaccountid"] = new EntityReference("account", parentAcc);
 account["address1_addresstypecode"] = new OptionSetValue(2);

ServiceContext.ClearChanges();

ServiceContext.Attach(account);

ServiceContext.UpdateObject(account);

ServiceContext.SaveChanges();

 }


 }
 catch (FaultException<OrganizationServiceFault> ex)

 {

 }
 catch (Exception ex)





 {


 throw;

 }

 }

 }