/// <summary> /// Traces the specified message. By default, is guaranteed to not throw an exception. /// </summary> /// <param name="format">The message format.</param> /// <param name="args">Optional Args</param> public void Trace(string format, params object[] args) { TracingService.Trace(format, args); }
public string GetNextPermitNumber() { //Retrieve the autonumbering record QueryExpression query = new QueryExpression("defra_autonumbering") { ColumnSet = new ColumnSet("defra_locked"), Criteria = new FilterExpression() { Conditions = { new ConditionExpression("statecode", ConditionOperator.Equal, 0) //new ConditionExpression("defra_name", ConditionOperator.Equal, "Waste"); } } }; EntityCollection results = Service.RetrieveMultiple(query); //Throw an exception if the autonumbering record does not exist if (results.Entities.Count == 0) { throw new InvalidPluginExecutionException("The autonumbering record cannot be found!"); } //Pre-lock the autonumbering table. Refer to the Microsoft Scalability White Paper for more details https://www.microsoft.com/en-us/download/details.aspx?id=45905 Entity autoNum = new Entity(results.Entities[0].LogicalName) { Id = results.Entities[0].Id }; autoNum["defra_locked"] = true; Service.Update(autoNum); //Retrieve safely the autonumbering record var lockedAutonumber = Service.Retrieve(autoNum.LogicalName, autoNum.Id, new ColumnSet(new string[] { "defra_prefix", "defra_suffix", "defra_currentnumber" })); var currentNumber = (int)lockedAutonumber["defra_currentnumber"]; var prefix = lockedAutonumber.GetAttributeValue <string>("defra_prefix"); var suffix = lockedAutonumber.GetAttributeValue <string>("defra_suffix"); // Increment suffix if (currentNumber == 9999) { currentNumber = 1; suffix = GetNextSuffix(suffix); } else { ++currentNumber; } TracingService.Trace("CurrentNumber: {0}", currentNumber.ToString("0000")); TracingService.Trace("Suffix: {0}", suffix); var nextPermitNumber = string.Format("{0}{1}{2}", prefix, currentNumber.ToString("0000"), suffix); //Update the sequence number var counterUpdater = new Entity(autoNum.LogicalName); counterUpdater.Id = autoNum.Id; counterUpdater["defra_currentnumber"] = currentNumber; counterUpdater["defra_suffix"] = suffix; counterUpdater["defra_locked"] = false; Service.Update(counterUpdater); TracingService.Trace("Exiting GetNextPermitNumber, Correlation Id: {0}", Context.CorrelationId); return(nextPermitNumber); }
/// <summary> /// Logs the exception. /// </summary> /// <param name="ex">The exception.</param> public virtual void LogException(Exception ex) { TracingService.Trace("Exception: {0}", ex.ToStringWithCallStack()); TracingService.Trace(this.GetContextInfo()); }
public void Execute(IServiceProvider serviceProvider) { //Extract the tracing service for use in debugging sandboxed plug-ins. TracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); // Obtain the execution context from the service provider. IPluginExecutionContext context = (IPluginExecutionContext) serviceProvider.GetService(typeof(IPluginExecutionContext)); // The InputParameters collection contains all the data passed in the message request. if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) { // Obtain the target entity from the input parameters. Entity target = (Entity)context.InputParameters["Target"]; // Verify that the target entity represents an account. // If not, this plug-in was not registered correctly. if (target.LogicalName != EntityName) { TracingService.Trace("Plugin is not propertly registered ({0} instead of {1})", target.LogicalName, EntityName); return; } try { TracingService.Trace("Only one featured news/events plugin."); // Only run if ace_featured attribute was changed... if (!target.Attributes.Contains(Field)) { return; } // Only run if ace_featured is true if ((bool)target.Attributes[Field] == false) { TracingService.Trace($"{0} is false.", Field); return; } // Obtain the organization service reference. IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); Service = serviceFactory.CreateOrganizationService(context.UserId); // Update other records (set flag to false where needed) var query = CreateQuery(target.Id); if (query is null) { return; } var results = Service.RetrieveMultiple(query); foreach (var entity in results.Entities) { entity[Field] = false; TracingService.Trace("About to update record {0}", entity.Id); Service.Update(entity); } TracingService.Trace("Done!"); } catch (FaultException <OrganizationServiceFault> ex) { TracingService.Trace("Fault: {0} {1}", ex.Message, ex.StackTrace); throw new InvalidPluginExecutionException("An error occurred.", ex); } catch (Exception ex) { TracingService.Trace("Unhandled general exception: {0}", ex.ToString()); throw; } } }
public void Trace(string message) { TracingService.Trace(message, new object[0]); }
/* * Creates new related lys_invoice if there are no other related invoices for the agreement. * * agreement - lys_agreement. */ public void CreateFirstRelatedInvoice(lys_agreement agreement, Guid emailNotificationSenderId) { TracingService.Trace($"agreementId={agreement.Id}"); if (HasRelatedInvoices(agreement)) { return; } // Checking if agreement contains required data. If not, obtaining it from CRM. if (agreement.lys_name == null || agreement.lys_summ == null || agreement.lys_contact == null) { BaseRepository <lys_agreement> agreementRepo = new BaseRepository <lys_agreement>(Service, lys_agreement.EntityLogicalName); agreement = agreementRepo.Get(agreement.Id, new ColumnSet(lys_agreement.Fields.lys_name, lys_agreement.Fields.lys_summ, lys_agreement.Fields.lys_contact)); } // Creating new invoice. lys_invoice newRelatedInvoice = new lys_invoice(); newRelatedInvoice.lys_name = string.Format("Счет для договора {0}", agreement.lys_name); newRelatedInvoice.lys_paydate = newRelatedInvoice.lys_date = DateTime.Now; newRelatedInvoice.lys_dogovorid = new EntityReference(lys_agreement.EntityLogicalName, agreement.Id); newRelatedInvoice.lys_fact = false; newRelatedInvoice.lys_type = lys_invoice_lys_type.Avtomaticheskoe_sozdanie; newRelatedInvoice.lys_amount = agreement.lys_summ; BaseRepository <lys_invoice> invoiceRepo = new BaseRepository <lys_invoice>(Service, lys_invoice.EntityLogicalName); Guid createdInvoiceId = invoiceRepo.Insert(newRelatedInvoice); TracingService.Trace($"Created new related lys_invoice with ID={createdInvoiceId} for agreementId={agreement.Id}"); // Getting agreement's related contact. BaseRepository <Contact> contactRepo = new BaseRepository <Contact>(Service, Contact.EntityLogicalName); Contact relatedContact = contactRepo.Get(agreement.lys_contact.Id, new ColumnSet(Contact.Fields.FullName, Contact.Fields.EMailAddress1, Contact.Fields.DoNotBulkEMail)); // Sending email to related contact if they hasn't opted out of emails and their email address is set. if (relatedContact.DoNotBulkEMail.HasValue && !relatedContact.DoNotBulkEMail.Value && relatedContact.EMailAddress1 != null) { // Forming Email message. ActivityParty senderParty = new ActivityParty(); senderParty.PartyId = new EntityReference(SystemUser.EntityLogicalName, emailNotificationSenderId); ActivityParty receiverParty = new ActivityParty(); receiverParty.PartyId = new EntityReference(Contact.EntityLogicalName, relatedContact.Id); Email emailMessage = new Email(); emailMessage.Subject = string.Format("Вам выставлен счет для оплаты договора {0}", agreement.lys_name); emailMessage.From = new[] { senderParty }; emailMessage.To = new[] { receiverParty }; emailMessage.Description = string.Format("Уважаемый(ая) {0}, по вашему договору {1} выставлен счет на сумму {2}.", relatedContact.FullName, agreement.lys_name, agreement.lys_summ.Value.ToString("0.##")); // Sending Email. SendEmailRequest emailRequest = new SendEmailRequest(); emailRequest.EmailId = Service.Create(emailMessage); // Creating Email Entity and getting its ID emailRequest.IssueSend = true; // Actually sending the email. emailRequest.TrackingToken = ""; Service.Execute(emailRequest); TracingService.Trace($"Sent notification email to related contact with ID={relatedContact.Id} at email={relatedContact.EMailAddress1}"); } }
/// <summary> /// Validates the registration requirements against the runtime execution. Requirements can be specified with "RegistrationInfo"-attributes on plugin class level /// Returns false if none of the registration set requirements is valid, returns true if at least one set of registration requirement is valid. /// </summary> /// <param name="pluginType">Pass the type of your plugin class - e.g. typeof(yourplugin)</param> /// <param name="throwError">Throw an exception instead of returning false</param> /// <returns></returns> public bool ValidateExecutionContext(Type pluginType, bool throwError) { int numberOfRegistrationRequirements = 0; string validationErrors = string.Empty; System.Reflection.MemberInfo pluginTypeInfo = pluginType; object[] attributes = pluginTypeInfo.GetCustomAttributes(true); TracingService.Trace("----- Start Execution Context Validation -----"); foreach (object attribute in attributes) { if (attribute is RegistrationInfo) { RegistrationInfo registrationInfo = attribute as RegistrationInfo; numberOfRegistrationRequirements++; bool isValid = false; bool messageNameIsEqual = true; bool modeIsEqual = true; bool stageIsEqual = true; bool preEntityImageNameIsEqual = true; bool primaryEntityNameIsEqual = true; bool postEntityImageNameIsEqual = true; TracingService.Trace("-- Registration Requirement {0}", numberOfRegistrationRequirements); if (!String.IsNullOrEmpty(registrationInfo.MessageName)) { messageNameIsEqual = (PluginExecutionContext.MessageName == registrationInfo.MessageName); TracingService.Trace("---- messageNameIsEqual : " + messageNameIsEqual); } if (!String.IsNullOrEmpty(registrationInfo.PrimaryEntityName)) { primaryEntityNameIsEqual = (PluginExecutionContext.PrimaryEntityName == registrationInfo.PrimaryEntityName); TracingService.Trace("---- primaryEntityNameIsEqual (" + PluginExecutionContext.PrimaryEntityName + ") : " + primaryEntityNameIsEqual); } //if (registrationInfo.Mode != 0) // Mode will always be validated (also if it is not specified) because an int value will always be initiated to 0. //{ modeIsEqual = (PluginExecutionContext.Mode == registrationInfo.Mode); TracingService.Trace("---- modeIsEqual : " + modeIsEqual); //} if (registrationInfo.Stage != 0) { stageIsEqual = (PluginExecutionContext.Stage == registrationInfo.Stage); TracingService.Trace("---- stageIsEqual : " + stageIsEqual); } if (!String.IsNullOrEmpty(registrationInfo.PreEntityImageName)) { CRMImage preEntityImage = new CRMImage(registrationInfo.PreEntityImageName); preEntityImageNameIsEqual = PluginExecutionContext.PreEntityImages.ContainsKey(preEntityImage.Name); TracingService.Trace("---- preEntityImageNameIsEqual : " + preEntityImageNameIsEqual); } if (!String.IsNullOrEmpty(registrationInfo.PostEntityImageName)) { CRMImage postEntityImage = new CRMImage(registrationInfo.PostEntityImageName); postEntityImageNameIsEqual = PluginExecutionContext.PostEntityImages.ContainsKey(postEntityImage.Name); TracingService.Trace("---- postEntityImageNameIsEqual : " + postEntityImageNameIsEqual); } isValid = messageNameIsEqual && primaryEntityNameIsEqual && stageIsEqual && preEntityImageNameIsEqual && postEntityImageNameIsEqual; if (isValid) { TracingService.Trace("----- End Execution Context Validation -----"); return(true); } validationErrors += numberOfRegistrationRequirements + ") " + registrationInfo.ToString() + Environment.NewLine; } } if (numberOfRegistrationRequirements > 0) { TracingService.Trace("----- End Execution Context Validation -----"); if (throwError) { throw new Exception(String.Format("Incorrect Plugin registration, none of the specified registration requirements are valid : {0}", validationErrors)); } return(false); } return(true); }
public void Trace(string message) { TracingService.Trace(message); }
public void CreateRelatedCreditInvoices(lys_agreement agreement) { TracingService.Trace($"agreementId={agreement.Id}"); BaseRepository <lys_agreement> agreementRepo = new BaseRepository <lys_agreement>(Service, lys_agreement.EntityLogicalName); BaseRepository <lys_invoice> invoiceRepo = new BaseRepository <lys_invoice>(Service, lys_invoice.EntityLogicalName); // Retrieving all related invoices. QueryExpression query = new QueryExpression(); query.ColumnSet = new ColumnSet(lys_invoice.Fields.lys_type, lys_invoice.Fields.lys_fact); query.Criteria.AddCondition(lys_invoice.Fields.lys_dogovorid, ConditionOperator.Equal, agreement.Id); EntityCollection relatedInvoices = invoiceRepo.GetMultiple(query); TracingService.Trace($"[lys_invoices] ec={relatedInvoices}, ec.Entities={relatedInvoices.Entities}, ec.Entities.Count={relatedInvoices.Entities.Count}"); // Checking if there are any paid or manually created related invoices. foreach (Entity entity in relatedInvoices.Entities) { lys_invoice invoice = (lys_invoice)entity; if (invoice.lys_fact == true || invoice.lys_type == lys_invoice_lys_type.Ruchnoe_sozdanie) { return; } } // Checking if agreement contains required data. If not, obtaining it from CRM. if (agreement.lys_creditid == null || agreement.lys_creditperiod == null || agreement.lys_creditamount == null || agreement.lys_name == null) { agreement = agreementRepo.Get(agreement.Id, new ColumnSet(lys_agreement.Fields.lys_creditid, lys_agreement.Fields.lys_creditperiod, lys_agreement.Fields.lys_creditamount, lys_agreement.Fields.lys_name)); // Checking if agreement has all required optional fields set. if (agreement.lys_creditid == null || agreement.lys_creditperiod == null || agreement.lys_creditamount == null) { return; } } // Deleting all existing automatically created related invoices. foreach (Entity entity in relatedInvoices.Entities) { invoiceRepo.Delete(entity.Id); } // Creating new related invoices based on the credit information. int creditPeriodMonths = agreement.lys_creditperiod.Value * 12; Decimal monthlyCreditAmount = agreement.lys_creditamount.Value / creditPeriodMonths; DateTime nextInvoiceDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(1); for (int i = 0; i < creditPeriodMonths; ++i) { lys_invoice newRelatedInvoice = new lys_invoice(); newRelatedInvoice.lys_name = string.Format("Кредитный счет #{0} для договора {1}", i + 1, agreement.lys_name); newRelatedInvoice.lys_date = nextInvoiceDate; newRelatedInvoice.lys_paydate = newRelatedInvoice.lys_date; newRelatedInvoice.lys_dogovorid = agreement.ToEntityReference(); newRelatedInvoice.lys_fact = false; newRelatedInvoice.lys_type = lys_invoice_lys_type.Avtomaticheskoe_sozdanie; newRelatedInvoice.lys_amount = new Money(monthlyCreditAmount); invoiceRepo.Insert(newRelatedInvoice); nextInvoiceDate = nextInvoiceDate.AddMonths(1); } // Updating agreement's payment plan date. lys_agreement agreementToUpdate = new lys_agreement(); agreementToUpdate.Id = agreement.Id; agreementToUpdate.lys_paymentplandate = DateTime.Now.AddDays(1); agreementRepo.Update(agreementToUpdate); TracingService.Trace($"Created {creditPeriodMonths} new lys_invoices related to lys_agreement with ID={agreement.Id}"); }
protected override void ExecuteLogic() { // get the triggering record var target = (Entity)Context.InputParameters["Target"]; var rawSerialisedEntries = target.GetAttributeValue <string>("ldv_serialisedlogentries"); if (rawSerialisedEntries.IsEmpty()) { TracingService.Trace("rawSerialisedEntries is empty."); return; } TracingService.Trace("Decompressing log entries ..."); var serialisedEntries = rawSerialisedEntries .Decompress() .Split(new[] { "<|||>" }, StringSplitOptions.RemoveEmptyEntries); TracingService.Trace("Deserialising the log entries returning them to 'Entity' type ..."); var logEntries = serialisedEntries .Select(EntitySerializer.DeserializeObject) .ToEntity <LogEntry>() .Where(l => l.LogicalName == LogEntry.EntityLogicalName).ToList(); var guidMap = new Dictionary <Guid, Guid>(); TracingService.Trace("Clearing all previously generated GUIDs and creating entries ..."); foreach (var logEntry in logEntries) { var oldId = logEntry.Id; // clear entry ID because CRM generates sequential ones, which is faster to retrieve from SQL later logEntry.Id = Guid.Empty; logEntry.ParentLog = target.Id; var parentRef = logEntry.ParentLogEntry; // no parent, so can't be created! if (parentRef.HasValue) { // get the parent entry ID from the previously created entries guidMap.TryGetValue(parentRef.Value, out var newParentId); // set in this entry if (newParentId != Guid.Empty) { logEntry.ParentLogEntry = newParentId; } } guidMap[oldId] = logEntry.Id = Service.Create(logEntry); } TracingService.Trace("Clearing the compressed payload from the log ..."); var exceptionEntry = logEntries.AsEnumerable().Reverse().FirstOrDefault(l => l.ExceptionThrown == true); Service.Update( new Log { Id = target.Id, ExceptionLogEntry = exceptionEntry?.Id, ExceptionMessage = $"{exceptionEntry?.Message}" + $"{(exceptionEntry?.InnerExceptionMessage.IsFilled() == true ? $" | {exceptionEntry.InnerExceptionMessage}" : "")}", SerialisedLogEntries = null }); }
/// <summary> /// Returns a list of task definitions that apply to an application /// </summary> /// <param name="applicationId">Application Guid</param> /// <param name="applicationSubTypeId">Optional filter by Application Sub Type, otherwise check for null</param> /// /// <param name="applicationTypeValue">Optional filter by Application Type, otherwise check for null</param> /// <param name="filterByTaskTypeIds">Task Types to filter by</param> /// <returns>List of defra_applicationtaskdefinition ids </returns> public List <Guid> GetTaskDefinitionIdsThatApplyToApplication(Guid applicationId, int?applicationTypeValue, Guid?applicationSubTypeId, params Guid[] filterByTaskTypeIds) { TracingService.Trace($"GetTaskDefinitionIdsThatApplyToApplication({applicationId}, {filterByTaskTypeIds}) Start..."); // Query defra_applicationtaskdefinition var query = new QueryExpression(defra_applicationtaskdefinition.EntityLogicalName) { Distinct = true }; query.ColumnSet.AddColumns( defra_applicationtaskdefinition.Fields.defra_name, defra_applicationtaskdefinition.Fields.defra_shortname, defra_applicationtaskdefinition.Fields.defra_applicationtaskdefinitionId); query.Criteria.AddCondition(defra_applicationtaskdefinition.Fields.StateCode, ConditionOperator.Equal, (int)defra_applicationtaskdefinitionState.Active); // Link to defra_itemapplicationtaskdefinition - the linker entity var linkQuery = query.AddLink( defra_itemapplicationtaskdefinition.EntityLogicalName, defra_applicationtaskdefinition.Fields.defra_tasktypeid, defra_itemapplicationtaskdefinition.Fields.defra_applicationtasktypeid); linkQuery.LinkCriteria.AddCondition(defra_itemapplicationtaskdefinition.Fields.StateCode, ConditionOperator.Equal, (int)defra_itemapplicationtaskdefinitionState.Active); linkQuery.LinkCriteria.AddCondition(defra_itemapplicationtaskdefinition.Fields.defra_scope, ConditionOperator.Equal, (int)defra_application_task_scope.Application); // Filter defra_itemapplicationtaskdefinition by application type if (applicationTypeValue.HasValue) { linkQuery.LinkCriteria.AddCondition(defra_itemapplicationtaskdefinition.Fields.defra_applicationtype, ConditionOperator.Equal, applicationTypeValue.Value); } else { linkQuery.LinkCriteria.AddCondition(defra_itemapplicationtaskdefinition.Fields.defra_applicationtype, ConditionOperator.Null); } // Filter defra_itemapplicationtaskdefinition by application sub type if (applicationSubTypeId.HasValue) { linkQuery.LinkCriteria.AddCondition(defra_itemapplicationtaskdefinition.Fields.defra_application_subtype, ConditionOperator.Equal, applicationSubTypeId.Value); } else { linkQuery.LinkCriteria.AddCondition(defra_itemapplicationtaskdefinition.Fields.defra_application_subtype, ConditionOperator.Null); } // Link to defra_standardrule var linkToStandardRule = linkQuery.AddLink( defra_standardrule.EntityLogicalName, defra_itemapplicationtaskdefinition.Fields.defra_standardruleid, defra_standardrule.Fields.defra_standardruleId); linkToStandardRule.LinkCriteria.AddCondition(defra_standardrule.Fields.StateCode, ConditionOperator.Equal, (int)defra_standardruleState.Active); // Link to defra_applicationline var linkToAppLine = linkToStandardRule.AddLink( defra_applicationline.EntityLogicalName, defra_standardrule.Fields.defra_standardruleId, defra_applicationline.Fields.defra_standardruleId); linkToAppLine.LinkCriteria.AddCondition(defra_applicationline.Fields.StateCode, ConditionOperator.Equal, (int)defra_applicationlineState.Active); linkToAppLine.LinkCriteria.AddCondition(defra_applicationline.Fields.defra_applicationId, ConditionOperator.Equal, applicationId); // Link to defra_tasktype var linkToType = query.AddLink(defra_tasktype.EntityLogicalName, defra_applicationtaskdefinition.Fields.defra_tasktypeid, defra_tasktype.Fields.defra_tasktypeId); // Filter by Active Task Types linkToType.LinkCriteria.AddCondition(defra_tasktype.Fields.StateCode, ConditionOperator.Equal, (int)defra_tasktypeState.Active); // Filter by specific Task Types (e.g. duly making checklist) if (filterByTaskTypeIds != null && filterByTaskTypeIds.Length > 0) { var filterTaskType = new FilterExpression(); linkToType.LinkCriteria.AddFilter(filterTaskType); filterTaskType.FilterOperator = LogicalOperator.Or; foreach (Guid taskTypeId in filterByTaskTypeIds) { filterTaskType.AddCondition(defra_tasktype.Fields.defra_tasktypeId, ConditionOperator.Equal, taskTypeId); } } // Query CRM EntityCollection entityCollectionResult = OrganisationService.RetrieveMultiple(query); // Return a list of defra_applicationtaskdefinition ids List <Guid> retVal = null; if (entityCollectionResult?.Entities != null) { TracingService.Trace(string.Format("entityCollectionResult.count: {0}", entityCollectionResult.Entities.Count.ToString())); TracingService.Trace("GetTaskDefinitionIdsThatApplyToApplication() Returning data"); retVal = entityCollectionResult.Entities .Select(e => e.GetAttributeIdOrDefault(defra_applicationtaskdefinition.Fields .defra_applicationtaskdefinitionId)).ToList(); } retVal?.ForEach(t => TracingService.Trace($"GetTaskDefinitionIdsThatApplyToApplication - {t}")); TracingService.Trace($"GetTaskDefinitionIdsThatApplyToApplication() Done"); return(retVal); }
protected Log(IServiceProvider serviceProvider, bool useCurrentUserId, bool instantiateOrganizationServiceFromServiceProvider) : base(serviceProvider, useCurrentUserId, instantiateOrganizationServiceFromServiceProvider) { TracingService.Trace("CrmServiceBase instantiated : useCurrentUserId: {0}, instantiateOrganizationServiceFromServiceProvider: {1} ", useCurrentUserId, instantiateOrganizationServiceFromServiceProvider); }
public override VoidEvent Execute(BranchedEvent1 @event) { TracingService.Trace(nameof(BranchedEvent1Handler)); return(VoidEvent); }
public PipelineBase(IOrganizationService service = null) { if (service == null) { FakeService = new FakeOrganzationService(); Service = FakeService; } else { Service = service; } CorrelationId = Guid.NewGuid(); RequestId = Guid.NewGuid(); OperationId = Guid.NewGuid(); OperationCreatedOn = DateTime.UtcNow; PreImages = new EntityImageCollection(); PostImages = new EntityImageCollection(); InputParameters = new ParameterCollection(); OutputParameters = new ParameterCollection(); PluginExecutionContext = A.Fake <IPluginExecutionContext>(a => a.Strict()); A.CallTo(() => PluginExecutionContext.PreEntityImages).Returns(PreImages); A.CallTo(() => PluginExecutionContext.PostEntityImages).Returns(PostImages); A.CallTo(() => PluginExecutionContext.InputParameters).Returns(InputParameters); A.CallTo(() => PluginExecutionContext.OutputParameters).Returns(OutputParameters); // ITracingService TracingService = A.Fake <ITracingService>((a) => a.Strict()); A.CallTo(() => TracingService.Trace(A <string> .Ignored, A <object[]> .Ignored)) .Invokes((string format, object[] args) => { if (args != null && args.Length > 0) { Trace.WriteLine(string.Format(format, args)); } else { Trace.WriteLine(format); } }); // IOrganizationServiceFactory Factory = A.Fake <IOrganizationServiceFactory>((a) => a.Strict()); A.CallTo(() => Factory.CreateOrganizationService(A <Guid?> .Ignored)).Returns(Service); // IServiceProvider ServiceProvider = A.Fake <IServiceProvider>((a) => a.Strict()); A.CallTo(() => ServiceProvider.GetService(A <Type> .Ignored)) .ReturnsLazily((objectcall) => { var type = (Type)objectcall.Arguments[0]; if (type == typeof(IPluginExecutionContext)) { return(PluginExecutionContext); } else if (type == typeof(ITracingService)) { return(TracingService); } else if (type == typeof(IOrganizationServiceFactory)) { return(Factory); } return(null); }); }