diff --git a/src/XrmMockup365/Core.cs b/src/XrmMockup365/Core.cs index deb87a2e..99eee263 100644 --- a/src/XrmMockup365/Core.cs +++ b/src/XrmMockup365/Core.cs @@ -731,8 +731,8 @@ internal OrganizationResponse Execute(OrganizationRequest request, EntityReferen MessageName = RequestNameToMessageName(request.RequestName), Depth = 1, ExtensionDepth = 1, - OrganizationName = this.OrganizationName, - OrganizationId = this.OrganizationId, + OrganizationName = OrganizationName, + OrganizationId = OrganizationId, PrimaryEntityName = primaryRef?.LogicalName, }; if (primaryRef != null) @@ -757,7 +757,10 @@ internal OrganizationResponse Execute(OrganizationRequest request, EntityReferen var buRef = GetBusinessUnit(userRef); pluginContext.BusinessUnitId = buRef.Id; - Mappings.RequestToEventOperation.TryGetValue(request.GetType(), out var eventOp); + // Get the request message from the mapping, if present, otherwise use the RequestName + var requestMessage = Mappings.RequestToEventOperation.TryGetValue(request.GetType(), out var eventOperation) + ? eventOperation.ToString() + : request.RequestName; var entityInfo = GetEntityInfo(request); @@ -778,12 +781,12 @@ internal OrganizationResponse Execute(OrganizationRequest request, EntityReferen if (preImage != null) primaryRef.Id = preImage.Id; - if (shouldTrigger && eventOp is EventOperation preValidationOperation) + if (shouldTrigger) { // System Pre-validation - pluginManager.TriggerSystem(preValidationOperation, ExecutionStage.PreValidation, entityInfo.Item1, preImage, null, pluginContext, this); + pluginManager.TriggerSystem(requestMessage, ExecutionStage.PreValidation, entityInfo.Item1, preImage, null, pluginContext, this); // Pre-validation - pluginManager.TriggerSync(preValidationOperation, ExecutionStage.PreValidation, entityInfo.Item1, preImage, null, pluginContext, this, (_) => true); + pluginManager.TriggerSync(requestMessage, ExecutionStage.PreValidation, entityInfo.Item1, preImage, null, pluginContext, this, (_) => true); } //perform security checks for the request @@ -792,19 +795,19 @@ internal OrganizationResponse Execute(OrganizationRequest request, EntityReferen //perform initialization of preoperation InitializePreOperation(request, userRef, preImage); - if (shouldTrigger && eventOp is EventOperation preOperationOperation) + if (shouldTrigger) { // Shared variables should be moved to parent context when transitioning from 10 to 20. pluginContext.ParentContext = pluginContext.Clone(); pluginContext.SharedVariables.Clear(); // Pre-operation - pluginManager.TriggerSync(preOperationOperation, ExecutionStage.PreOperation, entityInfo.Item1, preImage, null, pluginContext, this, (p) => p.GetExecutionOrder() == 0); - workflowManager.TriggerSync(preOperationOperation, ExecutionStage.PreOperation, entityInfo.Item1, preImage, null, pluginContext, this); - pluginManager.TriggerSync(preOperationOperation, ExecutionStage.PreOperation, entityInfo.Item1, preImage, null, pluginContext, this, (p) => p.GetExecutionOrder() != 0); + pluginManager.TriggerSync(requestMessage, ExecutionStage.PreOperation, entityInfo.Item1, preImage, null, pluginContext, this, (p) => p.GetExecutionOrder() == 0); + workflowManager.TriggerSync(requestMessage, ExecutionStage.PreOperation, entityInfo.Item1, preImage, null, pluginContext, this); + pluginManager.TriggerSync(requestMessage, ExecutionStage.PreOperation, entityInfo.Item1, preImage, null, pluginContext, this, (p) => p.GetExecutionOrder() != 0); // System Pre-operation - pluginManager.TriggerSystem(preOperationOperation, ExecutionStage.PreOperation, entityInfo.Item1, preImage, null, pluginContext, this); + pluginManager.TriggerSystem(requestMessage, ExecutionStage.PreOperation, entityInfo.Item1, preImage, null, pluginContext, this); } // Core operation @@ -824,26 +827,23 @@ internal OrganizationResponse Execute(OrganizationRequest request, EntityReferen pluginContext.OutputParameters["BusinessEntity"] = TryRetrieve((request as RetrieveRequest).Target); } - if (eventOp is EventOperation postOperationOperation) - { - var syncPostImage = TryRetrieve(primaryRef); + var syncPostImage = TryRetrieve(primaryRef); - //copy the createon etc system attributes onto the target so they are available for postoperation processing - if (syncPostImage != null) - { - CopySystemAttributes(syncPostImage, entityInfo.Item1 as Entity); - } + //copy the createon etc system attributes onto the target so they are available for postoperation processing + if (syncPostImage != null) + { + CopySystemAttributes(syncPostImage, entityInfo.Item1 as Entity); + } - pluginManager.TriggerSystem(postOperationOperation, ExecutionStage.PostOperation, entityInfo.Item1, preImage, syncPostImage, pluginContext, this); + pluginManager.TriggerSystem(requestMessage, ExecutionStage.PostOperation, entityInfo.Item1, preImage, syncPostImage, pluginContext, this); - pluginManager.TriggerSync(postOperationOperation, ExecutionStage.PostOperation, entityInfo.Item1, preImage, syncPostImage, pluginContext, this, (p) => p.GetExecutionOrder() == 0); - workflowManager.TriggerSync(postOperationOperation, ExecutionStage.PostOperation, entityInfo.Item1, preImage, syncPostImage, pluginContext, this); - pluginManager.TriggerSync(postOperationOperation, ExecutionStage.PostOperation, entityInfo.Item1, preImage, syncPostImage, pluginContext, this, (p) => p.GetExecutionOrder() != 0); + pluginManager.TriggerSync(requestMessage, ExecutionStage.PostOperation, entityInfo.Item1, preImage, syncPostImage, pluginContext, this, (p) => p.GetExecutionOrder() == 0); + workflowManager.TriggerSync(requestMessage, ExecutionStage.PostOperation, entityInfo.Item1, preImage, syncPostImage, pluginContext, this); + pluginManager.TriggerSync(requestMessage, ExecutionStage.PostOperation, entityInfo.Item1, preImage, syncPostImage, pluginContext, this, (p) => p.GetExecutionOrder() != 0); - var asyncPostImage = TryRetrieve(primaryRef); - pluginManager.StageAsync(postOperationOperation, ExecutionStage.PostOperation, entityInfo.Item1, preImage, asyncPostImage, pluginContext, this); - workflowManager.StageAsync(postOperationOperation, ExecutionStage.PostOperation, entityInfo.Item1, preImage, asyncPostImage, pluginContext, this); - } + var asyncPostImage = TryRetrieve(primaryRef); + pluginManager.StageAsync(requestMessage, ExecutionStage.PostOperation, entityInfo.Item1, preImage, asyncPostImage, pluginContext, this); + workflowManager.StageAsync(requestMessage, ExecutionStage.PostOperation, entityInfo.Item1, preImage, asyncPostImage, pluginContext, this); //When last Sync has been executed we trigger the Async jobs. if (parentPluginContext == null) diff --git a/src/XrmMockup365/Extensions/StringExtensions.cs b/src/XrmMockup365/Extensions/StringExtensions.cs new file mode 100644 index 00000000..b62bc143 --- /dev/null +++ b/src/XrmMockup365/Extensions/StringExtensions.cs @@ -0,0 +1,9 @@ +using XrmPluginCore.Enums; + +namespace DG.Tools.XrmMockup.Extensions +{ + internal static class StringExtensions + { + public static bool Matches(this string value, EventOperation operation) => value.Equals(operation.ToString()); + } +} diff --git a/src/XrmMockup365/Mappings.cs b/src/XrmMockup365/Mappings.cs index ea0ea6ef..1c7d94b9 100644 --- a/src/XrmMockup365/Mappings.cs +++ b/src/XrmMockup365/Mappings.cs @@ -7,12 +7,11 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; namespace DG.Tools.XrmMockup { - internal static partial class Mappings { - + internal static class Mappings + { public static Dictionary EntityImageProperty = new Dictionary() { { typeof(AssignRequest), nameof(AssignRequest.Target) }, diff --git a/src/XrmMockup365/Plugin/PluginManager.cs b/src/XrmMockup365/Plugin/PluginManager.cs index 1dd8c446..2e43752a 100644 --- a/src/XrmMockup365/Plugin/PluginManager.cs +++ b/src/XrmMockup365/Plugin/PluginManager.cs @@ -16,18 +16,22 @@ namespace DG.Tools.XrmMockup { + using StageToTriggerMap = Dictionary>; + using EventOperation = String; + using EventOperationEnum = EventOperation; + internal class PluginManager { // Static caches shared across all PluginManager instances - private static readonly ConcurrentDictionary>>> _cachedRegisteredPlugins = new ConcurrentDictionary>>>(); - private static readonly ConcurrentDictionary>>> _cachedSystemPlugins = new ConcurrentDictionary>>>(); + private static readonly ConcurrentDictionary> _cachedRegisteredPlugins = new ConcurrentDictionary>(); + private static readonly ConcurrentDictionary> _cachedSystemPlugins = new ConcurrentDictionary>(); private static readonly ConcurrentDictionary _pluginInstanceCache = new ConcurrentDictionary(); private static readonly object _cacheLock = new object(); // TODO: We can probably optimize lookup by creating a key record and using that instead of a Dictionary of Dictionaries - private readonly Dictionary>> registeredPlugins = new Dictionary>>(); - private readonly Dictionary>> temporaryPlugins = new Dictionary>>(); - private readonly Dictionary>> registeredSystemPlugins = new Dictionary>>(); + private readonly Dictionary registeredPlugins = new Dictionary(); + private readonly Dictionary temporaryPlugins = new Dictionary(); + private readonly Dictionary registeredSystemPlugins = new Dictionary(); internal readonly List missingRegistrations = new List(); @@ -54,7 +58,7 @@ internal class PluginManager public PluginManager(IEnumerable basePluginTypes, Dictionary metadata, List plugins) { - temporaryPlugins = new Dictionary>>(); + temporaryPlugins = new Dictionary(); var pluginCacheKey = GeneratePluginCacheKey(basePluginTypes); var systemCacheKey = "system_plugins"; @@ -79,8 +83,8 @@ public PluginManager(IEnumerable basePluginTypes, Dictionary>>(); - registeredSystemPlugins = new Dictionary>>(); + registeredPlugins = new Dictionary(); + registeredSystemPlugins = new Dictionary(); // TODO: Find all concrete types that implement IPlugin, handle system plugins separately // TODO: How do we filter CustomAPIs? @@ -102,7 +106,7 @@ public PluginManager(IEnumerable basePluginTypes, Dictionary TemporaryPluginRegistrations => FlattenPluginDictionary(temporaryPlugins); internal List SystemPluginRegistrations => FlattenPluginDictionary(registeredSystemPlugins); - private static List FlattenPluginDictionary(Dictionary>> plugins) + private static List FlattenPluginDictionary(Dictionary plugins) { return plugins .SelectMany(kvpOperation => @@ -113,7 +117,7 @@ private static List FlattenPluginDictionary(Dictionary basePluginTypes, Dictionary metadata, List plugins, Dictionary>> register) + private void RegisterPlugins(IEnumerable basePluginTypes, Dictionary metadata, List plugins, Dictionary register) { foreach (var basePluginType in basePluginTypes) { @@ -136,7 +140,7 @@ private void RegisterPlugins(IEnumerable basePluginTypes, Dictionary basePluginTypes, Dictionary metadata, List plugins, Dictionary>> register) + private void RegisterDirectPlugins(IEnumerable basePluginTypes, Dictionary metadata, List plugins, Dictionary register) { if (basePluginTypes == null) return; @@ -158,7 +162,7 @@ private void RegisterDirectPlugins(IEnumerable basePluginTypes, Dictionary SortAllLists(register); } - private void RegisterPlugin(Type pluginType, Dictionary metadata, List metaPlugins, Dictionary>> register) + private void RegisterPlugin(Type pluginType, Dictionary metadata, List metaPlugins, Dictionary register) { var plugin = _pluginInstanceCache.GetOrAdd(pluginType, Utility.CreatePluginInstance); if (plugin == null) @@ -212,7 +216,7 @@ public void RegisterAdditionalPlugin(Type pluginType, Dictionary>> register, Dictionary metadata) + private void RegisterSystemPlugins(Dictionary register, Dictionary metadata) { var registrations = new List(); @@ -232,14 +236,14 @@ private void RegisterSystemPlugins(Dictionary>> register) + private static void AddTrigger(PluginTrigger trigger, Dictionary register) { var operation = trigger.Operation; var stage = trigger.Stage; if (!register.TryGetValue(operation, out var operationRegister)) { - register[operation] = operationRegister = new Dictionary>(); + register[operation] = operationRegister = new StageToTriggerMap(); } if (!operationRegister.TryGetValue(stage, out var stageRegister)) @@ -253,7 +257,7 @@ private static void AddTrigger(PluginTrigger trigger, Dictionary /// Sorts all the registered which shares the same entry point based on their given order /// - private void SortAllLists(Dictionary>> plugins) + private void SortAllLists(Dictionary plugins) { foreach (var dictEntry in plugins) { @@ -264,13 +268,14 @@ private void SortAllLists(Dictionary executionOrderFilter) { TriggerSyncInternal(operation, stage, entity, preImage, postImage, pluginContext, core, executionOrderFilter); // Check if this is a Single -> Multiple request - if (Mappings.RequestToMultipleRequest.TryGetValue(operation, out var multipleOperation)) + var isKnownOp = Enum.TryParse(operation, out var knownOp); + if (isKnownOp && Mappings.RequestToMultipleRequest.TryGetValue(knownOp, out var multipleOperation)) { var multiplePluginContext = pluginContext.Clone(); var entityCollection = new EntityCollection() @@ -295,14 +300,14 @@ public void TriggerSync(EventOperation operation, ExecutionStage stage, : throw new MockupException($"Could not create request for operation {operation}"); // TODO: Images for multiple are handled in IPluginExecutionContext4 - TriggerSyncInternal(multipleOperation, stage, entityCollection, null, null, multiplePluginContext, core, executionOrderFilter); + TriggerSyncInternal(multipleOperation.ToString(), stage, entityCollection, null, null, multiplePluginContext, core, executionOrderFilter); } // Check if this is a Multiple -> Single request - if (Mappings.SingleOperationFromMultiple(operation) is EventOperation singleOperation) + if (isKnownOp && Mappings.SingleOperationFromMultiple(knownOp) is EventOperationEnum singleOperation) { // Try to get the request type for the multiple - var multipleRequestType = Mappings.EventOperationToRequest(operation) + var multipleRequestType = Mappings.EventOperationToRequest(knownOp) ?? throw new MockupException($"Could not find request type for operation {operation}"); // Now try to get the image property for the multiple request @@ -335,7 +340,7 @@ public void TriggerSync(EventOperation operation, ExecutionStage stage, singlePluginContext.MessageName = singleMessageName; // TODO: Recalculate preImage and postImage here - TriggerSyncInternal(singleOperation, stage, targetEntity, preImage, postImage, singlePluginContext, core, executionOrderFilter); + TriggerSyncInternal(singleOperation.ToString(), stage, targetEntity, preImage, postImage, singlePluginContext, core, executionOrderFilter); } } } @@ -423,12 +428,12 @@ private string GeneratePluginCacheKey(IEnumerable basePluginTypes) } } - private Dictionary>> ClonePluginDictionary(Dictionary>> source) + private Dictionary ClonePluginDictionary(Dictionary source) { - var result = new Dictionary>>(); + var result = new Dictionary(); foreach (var operationEntry in source) { - var stageDict = new Dictionary>(); + var stageDict = new StageToTriggerMap(); foreach (var stageEntry in operationEntry.Value) { stageDict[stageEntry.Key] = new List(stageEntry.Value); diff --git a/src/XrmMockup365/Plugin/PluginStepConfig.cs b/src/XrmMockup365/Plugin/PluginStepConfig.cs index 0c4bf986..19dd387d 100644 --- a/src/XrmMockup365/Plugin/PluginStepConfig.cs +++ b/src/XrmMockup365/Plugin/PluginStepConfig.cs @@ -11,7 +11,7 @@ internal class PluginStepConfig : IPluginStepConfig public string Name { get; internal set; } - public EventOperation EventOperation { get; internal set; } + public string EventOperation { get; internal set; } public ExecutionStage ExecutionStage { get; internal set; } diff --git a/src/XrmMockup365/Plugin/PluginTrigger.cs b/src/XrmMockup365/Plugin/PluginTrigger.cs index f6737fb5..fe8cd884 100644 --- a/src/XrmMockup365/Plugin/PluginTrigger.cs +++ b/src/XrmMockup365/Plugin/PluginTrigger.cs @@ -13,6 +13,7 @@ using XrmPluginCore.Interfaces.Plugin; using System.Diagnostics; using DG.Tools.XrmMockup.Internal; +using DG.Tools.XrmMockup.Extensions; namespace DG.Tools.XrmMockup { @@ -22,7 +23,7 @@ internal class PluginTrigger : IComparable public Action PluginExecute { get; } internal string EntityName { get; } - internal EventOperation Operation { get; } + internal string Operation { get; } internal ExecutionStage Stage { get; } internal ExecutionMode Mode { get; } internal int Order { get; } @@ -34,7 +35,7 @@ internal class PluginTrigger : IComparable private string DebuggerDisplay => $"{Stage} {Operation} {EntityName} [{string.Join(", ", Attributes)}]"; - public PluginTrigger(EventOperation operation, ExecutionStage stage, + public PluginTrigger(string operation, ExecutionStage stage, Action pluginExecute, IPluginStepConfig pluginRegistration, Dictionary metadata) { PluginExecute = pluginExecute; @@ -134,7 +135,7 @@ private void CheckInfiniteLoop(PluginContext pluginContext) private void CheckSpecialRequest() { - if (EntityName != "" && (Operation == EventOperation.Associate || Operation == EventOperation.Disassociate)) + if (EntityName != "" && (Operation.Matches(EventOperation.Associate) || Operation.Matches(EventOperation.Disassociate))) { throw new MockupException( $"An {Operation} plugin step was registered for a specific entity, which can only be registered on AnyEntity"); @@ -143,7 +144,7 @@ private void CheckSpecialRequest() private Entity AddPostImageAttributesToEntity(Entity entity, Entity preImage, Entity postImage) { - if (Operation == EventOperation.Update && Stage == ExecutionStage.PostOperation) + if (Operation.Matches(EventOperation.Update) && Stage == ExecutionStage.PostOperation) { var shadowAddedAttributes = postImage.Attributes.Where(a => !preImage.Attributes.ContainsKey(a.Key) && !entity.Attributes.ContainsKey(a.Key)); entity = entity.CloneEntity(); @@ -154,7 +155,7 @@ private Entity AddPostImageAttributesToEntity(Entity entity, Entity preImage, En private bool FilteredAttributesMatches(Entity entity) { - if (Operation != EventOperation.Update || Attributes.Count == 0) + if (!Operation.Matches(EventOperation.Update) || Attributes.Count == 0) { return true; } diff --git a/src/XrmMockup365/Plugin/RegistrationStrategy/DAXIF/PluginRegistrationStrategy.cs b/src/XrmMockup365/Plugin/RegistrationStrategy/DAXIF/PluginRegistrationStrategy.cs index 8a66a960..3e6a4353 100644 --- a/src/XrmMockup365/Plugin/RegistrationStrategy/DAXIF/PluginRegistrationStrategy.cs +++ b/src/XrmMockup365/Plugin/RegistrationStrategy/DAXIF/PluginRegistrationStrategy.cs @@ -31,17 +31,12 @@ public IEnumerable AnalyzeType(IPlugin plugin) return configs.Select(c => { - if (!Enum.TryParse(c.Item1.Item3, true, out var eventOperation)) - { - throw new MockupException($"Unknown message '{c.Item1.Item3}' for plugin '{plugin.GetType().FullName}'"); - } - var hasImpersonatingUser = Guid.TryParse(c.Item2.Item6, out var impersonatingUserId); return new PluginStepConfig { ExecutionStage = (ExecutionStage)c.Item1.Item2, - EventOperation = eventOperation, + EventOperation = c.Item1.Item3, EntityLogicalName = c.Item1.Item4, Deployment = (Deployment)c.Item2.Item1, ExecutionMode = (ExecutionMode)c.Item2.Item2, diff --git a/src/XrmMockup365/Plugin/RegistrationStrategy/MetadataRegistrationStrategy.cs b/src/XrmMockup365/Plugin/RegistrationStrategy/MetadataRegistrationStrategy.cs index b1f2beeb..5664665d 100644 --- a/src/XrmMockup365/Plugin/RegistrationStrategy/MetadataRegistrationStrategy.cs +++ b/src/XrmMockup365/Plugin/RegistrationStrategy/MetadataRegistrationStrategy.cs @@ -27,15 +27,10 @@ public IEnumerable AnalyzeType(Type pluginType, List(metaStep.MessageName, true, out var eventOperation)) - { - throw new MockupException($"Unknown message '{metaStep.MessageName}' for plugin '{pluginType.FullName}'"); - } - yield return new PluginStepConfig { ExecutionStage = (ExecutionStage)metaStep.Stage, - EventOperation = eventOperation, + EventOperation = metaStep.MessageName, EntityLogicalName = metaStep.PrimaryEntity, Deployment = 0, ExecutionMode = (ExecutionMode)metaStep.Mode, diff --git a/src/XrmMockup365/Plugin/RegistrationStrategy/XrmPluginCore/CustomApiRegistrationStrategy.cs b/src/XrmMockup365/Plugin/RegistrationStrategy/XrmPluginCore/CustomApiRegistrationStrategy.cs index efe7a6ed..e5bd14ff 100644 --- a/src/XrmMockup365/Plugin/RegistrationStrategy/XrmPluginCore/CustomApiRegistrationStrategy.cs +++ b/src/XrmMockup365/Plugin/RegistrationStrategy/XrmPluginCore/CustomApiRegistrationStrategy.cs @@ -1,8 +1,6 @@ -using DG.Tools.XrmMockup.Plugin.RegistrationStrategy; -using XrmPluginCore; +using XrmPluginCore; using XrmPluginCore.Interfaces.CustomApi; using Microsoft.Xrm.Sdk; -using System; using System.Collections.Generic; namespace DG.Tools.XrmMockup.Plugin.RegistrationStrategy.XrmPluginCore diff --git a/src/XrmMockup365/Plugin/RegistrationStrategy/XrmPluginCore/PluginRegistrationStrategy.cs b/src/XrmMockup365/Plugin/RegistrationStrategy/XrmPluginCore/PluginRegistrationStrategy.cs index db143420..bc6896a1 100644 --- a/src/XrmMockup365/Plugin/RegistrationStrategy/XrmPluginCore/PluginRegistrationStrategy.cs +++ b/src/XrmMockup365/Plugin/RegistrationStrategy/XrmPluginCore/PluginRegistrationStrategy.cs @@ -1,7 +1,6 @@ using XrmPluginCore; using XrmPluginCore.Interfaces.Plugin; using Microsoft.Xrm.Sdk; -using System; using System.Collections.Generic; using System.Linq; diff --git a/src/XrmMockup365/Plugin/SystemPlugins/AbstractSystemPlugin.cs b/src/XrmMockup365/Plugin/SystemPlugins/AbstractSystemPlugin.cs index 4af56fcb..460f3744 100644 --- a/src/XrmMockup365/Plugin/SystemPlugins/AbstractSystemPlugin.cs +++ b/src/XrmMockup365/Plugin/SystemPlugins/AbstractSystemPlugin.cs @@ -26,7 +26,7 @@ protected void RegisterPluginStep(string entityName, EventOperation eventOperati var stepConfig = new PluginStepConfig { ExecutionStage = executionStage, - EventOperation = eventOperation, + EventOperation = eventOperation.ToString(), EntityLogicalName = entityName, Deployment = Deployment.ServerOnly, ExecutionMode = ExecutionMode.Synchronous, @@ -72,7 +72,7 @@ public void Execute(IServiceProvider serviceProvider) (from a in PluginRegistrations where (int)a.PluginConfig.ExecutionStage == localcontext.PluginExecutionContext.Stage && - a.PluginConfig.EventOperation.ToString() == localcontext.PluginExecutionContext.MessageName && + a.PluginConfig.EventOperation == localcontext.PluginExecutionContext.MessageName && (string.IsNullOrWhiteSpace(a.PluginConfig.EntityLogicalName) || a.PluginConfig.EntityLogicalName == localcontext.PluginExecutionContext.PrimaryEntityName) select a.Action).FirstOrDefault(); diff --git a/src/XrmMockup365/Workflow/WorkflowManager.cs b/src/XrmMockup365/Workflow/WorkflowManager.cs index 0d209f1f..00708038 100644 --- a/src/XrmMockup365/Workflow/WorkflowManager.cs +++ b/src/XrmMockup365/Workflow/WorkflowManager.cs @@ -15,6 +15,7 @@ using System.Activities; using XrmPluginCore.Enums; using DG.Tools.XrmMockup.Internal; +using DG.Tools.XrmMockup.Extensions; namespace DG.Tools.XrmMockup { @@ -89,7 +90,7 @@ public WorkflowManager(IEnumerable codeActivityInstances, bool? IncludeAll /// /// /// - public void TriggerSync(EventOperation operation, ExecutionStage stage, + public void TriggerSync(string operation, ExecutionStage stage, object entity, Entity preImage, Entity postImage, PluginContext pluginContext, Core core) { var toExecute = synchronousWorkflows.Where(x => ShouldExecute(x, operation, stage, entity, pluginContext)).ToList(); @@ -118,7 +119,7 @@ public void TriggerAsync(Core core) } } - public void StageAsync(EventOperation operation, ExecutionStage stage, + public void StageAsync(string operation, ExecutionStage stage, object entity, Entity preImage, Entity postImage, PluginContext pluginContext, Core core) { var toExecute = asynchronousWorkflows.Where(x => ShouldStage(x, operation, stage, entity, pluginContext)).ToList(); @@ -181,7 +182,7 @@ private PluginContext createPluginContext(PluginContext pluginContext, Entity wo return thisPluginContext; } - private void Stage(Entity workflow, EventOperation operation, ExecutionStage stage, + private void Stage(Entity workflow, string operation, ExecutionStage stage, object entityObject, PluginContext pluginContext) { if (workflow.LogicalName != "workflow") return; @@ -195,9 +196,9 @@ private void Stage(Entity workflow, EventOperation operation, ExecutionStage sta checkInfiniteRecursion(pluginContext); - var isCreate = operation == EventOperation.Create; - var isUpdate = operation == EventOperation.Update; - var isDelete = operation == EventOperation.Delete; + var isCreate = operation.Matches(EventOperation.Create); + var isUpdate = operation.Matches(EventOperation.Update); + var isDelete = operation.Matches(EventOperation.Delete); if (!ShouldTriggerOnAction(isCreate, isUpdate, isDelete, workflow)) return; @@ -231,7 +232,7 @@ private void Stage(Entity workflow, EventOperation operation, ExecutionStage sta pendingAsyncWorkflows.Enqueue(new WorkflowExecutionContext(parsedWorkflow, thisPluginContext, new EntityReference(logicalName, guid))); } - private bool ShouldStage(Entity workflow, EventOperation operation, ExecutionStage stage, + private bool ShouldStage(Entity workflow, string operation, ExecutionStage stage, object entityObject, PluginContext pluginContext) { if (workflow.LogicalName != "workflow") return false; @@ -245,9 +246,9 @@ private bool ShouldStage(Entity workflow, EventOperation operation, ExecutionSta checkInfiniteRecursion(pluginContext); - var isCreate = operation == EventOperation.Create; - var isUpdate = operation == EventOperation.Update; - var isDelete = operation == EventOperation.Delete; + var isCreate = operation.Matches(EventOperation.Create); + var isUpdate = operation.Matches(EventOperation.Update); + var isDelete = operation.Matches(EventOperation.Delete); if (!ShouldTriggerOnAction(isCreate, isUpdate, isDelete, workflow)) return false; @@ -289,7 +290,7 @@ private bool ShouldTriggerOnAction(bool isCreate,bool isUpdate,bool isDelete,Ent return true; } - private bool ShouldExecute(Entity workflow, EventOperation operation, ExecutionStage stage, object entityObject, PluginContext pluginContext) + private bool ShouldExecute(Entity workflow, string operation, ExecutionStage stage, object entityObject, PluginContext pluginContext) { // Check if it is supposed to execute. Returns preemptively, if it should not. if (workflow.LogicalName != "workflow") return false; @@ -303,9 +304,9 @@ private bool ShouldExecute(Entity workflow, EventOperation operation, ExecutionS checkInfiniteRecursion(pluginContext); - var isCreate = operation == EventOperation.Create; - var isUpdate = operation == EventOperation.Update; - var isDelete = operation == EventOperation.Delete; + var isCreate = operation.Matches(EventOperation.Create); + var isUpdate = operation.Matches(EventOperation.Update); + var isDelete = operation.Matches(EventOperation.Delete); if (!ShouldTriggerOnAction(isCreate, isUpdate, isDelete, workflow)) return false; @@ -339,7 +340,7 @@ private bool ShouldExecute(Entity workflow, EventOperation operation, ExecutionS return true; } - private void Execute(Entity workflow, EventOperation operation, object entityObject, Entity preImage, Entity postImage, PluginContext pluginContext, Core core) + private void Execute(Entity workflow, string operation, object entityObject, Entity preImage, Entity postImage, PluginContext pluginContext, Core core) { // Check if it is supposed to execute. Returns preemptively, if it should not. var entity = entityObject as Entity; @@ -350,9 +351,9 @@ private void Execute(Entity workflow, EventOperation operation, object entityObj checkInfiniteRecursion(pluginContext); - var isCreate = operation == EventOperation.Create; - var isUpdate = operation == EventOperation.Update; - var isDelete = operation == EventOperation.Delete; + var isCreate = operation.Matches(EventOperation.Create); + var isUpdate = operation.Matches(EventOperation.Update); + var isDelete = operation.Matches(EventOperation.Delete); var triggerFields = new HashSet(); if (workflow.GetAttributeValue("triggeronupdateattributelist") != null) diff --git a/src/XrmMockup365/XrmMockup365.csproj b/src/XrmMockup365/XrmMockup365.csproj index 7734e15f..5291cf8a 100644 --- a/src/XrmMockup365/XrmMockup365.csproj +++ b/src/XrmMockup365/XrmMockup365.csproj @@ -78,7 +78,7 @@ - + diff --git a/tests/TestPluginAssembly365/Context/CustomEntity/ChildEntity.cs b/tests/TestPluginAssembly365/Context/CustomEntity/ChildEntity.cs new file mode 100644 index 00000000..1b422940 --- /dev/null +++ b/tests/TestPluginAssembly365/Context/CustomEntity/ChildEntity.cs @@ -0,0 +1,10 @@ +using Microsoft.Xrm.Sdk; + +namespace DG.Some.Namespace +{ + public class ChildEntity : Entity { + public ChildEntity() : base("mock_child") + { + } + } +} diff --git a/tests/TestPluginAssembly365/Context/CustomEntity/MockParent.cs b/tests/TestPluginAssembly365/Context/CustomEntity/MockParent.cs new file mode 100644 index 00000000..86fb8694 --- /dev/null +++ b/tests/TestPluginAssembly365/Context/CustomEntity/MockParent.cs @@ -0,0 +1,9 @@ +using Microsoft.Xrm.Sdk; +namespace DG.Some.Namespace +{ + public class MockParent : Entity + { + public MockParent() : base("mock_parent") + {} + } +} diff --git a/tests/TestPluginAssembly365/Plugins/ChildPreCreatePlugin.cs b/tests/TestPluginAssembly365/Plugins/ChildPreCreatePlugin.cs index 7e97975b..f85f4d87 100644 --- a/tests/TestPluginAssembly365/Plugins/ChildPreCreatePlugin.cs +++ b/tests/TestPluginAssembly365/Plugins/ChildPreCreatePlugin.cs @@ -1,18 +1,14 @@ -using System; -using System.Collections.Generic; -using System.ServiceModel; -using Microsoft.Xrm.Sdk; -using DG.XrmFramework.BusinessDomain.ServiceContext; +using Microsoft.Xrm.Sdk; using XrmPluginCore; using XrmPluginCore.Enums; -namespace DG.Some.Namespace +namespace DG.Some.Namespace { - public class ChildPreCreatePlugin : Plugin + public class ChildPreCreatePlugin : Plugin { public ChildPreCreatePlugin() { - RegisterPluginStep("mock_child", + RegisterPluginStep( EventOperation.Create, ExecutionStage.PreOperation, Execute).SetExecutionMode(ExecutionMode.Synchronous); diff --git a/tests/TestPluginAssembly365/Plugins/NotePostOperationPlugin.cs b/tests/TestPluginAssembly365/Plugins/NotePostOperationPlugin.cs index 44877fe9..6c4d2011 100644 --- a/tests/TestPluginAssembly365/Plugins/NotePostOperationPlugin.cs +++ b/tests/TestPluginAssembly365/Plugins/NotePostOperationPlugin.cs @@ -19,14 +19,20 @@ using XrmPluginCore.Enums; namespace DG.Some.Namespace { - + public class Annotation : Entity + { + public Annotation() : base("annotation") + { + + } + } public class NotePostOperationPlugin : Plugin { /// /// Initializes a new instance of the class. /// public NotePostOperationPlugin() { - RegisterPluginStep("annotation", + RegisterPluginStep( EventOperation.Update, ExecutionStage.PostOperation, Execute) diff --git a/tests/TestPluginAssembly365/Plugins/ParentPostCreatePlugin.cs b/tests/TestPluginAssembly365/Plugins/ParentPostCreatePlugin.cs index 3202b62b..9779a0ee 100644 --- a/tests/TestPluginAssembly365/Plugins/ParentPostCreatePlugin.cs +++ b/tests/TestPluginAssembly365/Plugins/ParentPostCreatePlugin.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ServiceModel; -using Microsoft.Xrm.Sdk; -using DG.XrmFramework.BusinessDomain.ServiceContext; +using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; using System.Linq; using Microsoft.Crm.Sdk.Messages; @@ -11,11 +7,11 @@ namespace DG.Some.Namespace { - public class ParentPostCreatePlugin : Plugin + public class ParentPostCreatePlugin : Plugin { public ParentPostCreatePlugin() { - RegisterPluginStep("mock_parent", + RegisterPluginStep( EventOperation.Create, ExecutionStage.PostOperation, Execute) diff --git a/tests/TestPluginAssembly365/TestPluginAssembly365.csproj b/tests/TestPluginAssembly365/TestPluginAssembly365.csproj index fc5a6ef0..1bcebfb5 100644 --- a/tests/TestPluginAssembly365/TestPluginAssembly365.csproj +++ b/tests/TestPluginAssembly365/TestPluginAssembly365.csproj @@ -49,6 +49,6 @@ - + \ No newline at end of file diff --git a/tests/XrmMockup365Test/XrmMockup365Test.csproj b/tests/XrmMockup365Test/XrmMockup365Test.csproj index f37bf105..eaa62e5f 100644 --- a/tests/XrmMockup365Test/XrmMockup365Test.csproj +++ b/tests/XrmMockup365Test/XrmMockup365Test.csproj @@ -46,7 +46,7 @@ - + all