private void AddInstanceExtension(WorkflowInstanceExtensionProvider extensionProvider) { Fx.Assert(_instanceExtensions != null, "instanceExtensions should be setup by now"); object newExtension = extensionProvider.ProvideValue(); if (newExtension is SymbolResolver) { throw CoreWf.Internals.FxTrace.Exception.AsError(new InvalidOperationException(SR.SymbolResolverMustBeSingleton)); } // for IWorkflowInstance we key off the type of the value, not the declared type if (!_shouldSetInstanceForInstanceExtensions && newExtension is IWorkflowInstanceExtension) { _shouldSetInstanceForInstanceExtensions = true; } if (!_hasTrackingParticipant && extensionProvider.IsMatch <TrackingParticipant>(newExtension)) { _hasTrackingParticipant = true; } if (!_hasPersistenceModule && extensionProvider.IsMatch <IPersistencePipelineModule>(newExtension)) { _hasPersistenceModule = true; } _instanceExtensions.Add(new KeyValuePair <WorkflowInstanceExtensionProvider, object>(extensionProvider, newExtension)); WorkflowInstanceExtensionManager.AddExtensionClosure(newExtension, ref _additionalInstanceExtensions, ref _hasTrackingParticipant, ref _hasPersistenceModule); }
// locks down the given extensions manager and runs cache metadata on the workflow definition protected void RegisterExtensionManager(WorkflowInstanceExtensionManager extensionManager) { ValidateWorkflow(extensionManager); _extensions = WorkflowInstanceExtensionManager.CreateInstanceExtensions(this.WorkflowDefinition, extensionManager); if (_extensions != null) { this.HasPersistenceModule = _extensions.HasPersistenceModule; } }
//void ThrowIfDynamicUpdateErrorExists(Collection<ActivityBlockingUpdate> updateErrors) //{ // if (updateErrors != null && updateErrors.Count > 0) // { // // update error found // // exit early // throw CoreWf.Internals.FxTrace.Exception.AsError(new InstanceUpdateException(updateErrors)); // } //} private void ValidateWorkflow(WorkflowInstanceExtensionManager extensionManager) { if (!WorkflowDefinition.IsRuntimeReady) { LocationReferenceEnvironment localEnvironment = _hostEnvironment; if (localEnvironment == null) { LocationReferenceEnvironment parentEnvironment = null; if (extensionManager != null && extensionManager.SymbolResolver != null) { parentEnvironment = extensionManager.SymbolResolver.AsLocationReferenceEnvironment(); } localEnvironment = new ActivityLocationReferenceEnvironment(parentEnvironment); } IList <ValidationError> validationErrors = null; ActivityUtilities.CacheRootMetadata(WorkflowDefinition, localEnvironment, ProcessActivityTreeOptions.FullCachingOptions, null, ref validationErrors); ActivityValidationServices.ThrowIfViolationsExist(validationErrors); } }
internal static WorkflowInstanceExtensionCollection CreateInstanceExtensions(Activity workflowDefinition, WorkflowInstanceExtensionManager extensionManager) { Fx.Assert(workflowDefinition.IsRuntimeReady, "activity should be ready with extensions after a successful CacheMetadata call"); if (extensionManager != null) { extensionManager.MakeReadOnly(); return(new WorkflowInstanceExtensionCollection(workflowDefinition, extensionManager)); } else if ((workflowDefinition.DefaultExtensionsCount > 0) || (workflowDefinition.RequiredExtensionTypesCount > 0)) { return(new WorkflowInstanceExtensionCollection(workflowDefinition, null)); } else { return(null); } }
internal WorkflowInstanceExtensionCollection(Activity workflowDefinition, WorkflowInstanceExtensionManager extensionManager) { _extensionManager = extensionManager; int extensionProviderCount = 0; if (extensionManager != null) { extensionProviderCount = extensionManager.ExtensionProviders.Count; _hasTrackingParticipant = extensionManager.HasSingletonTrackingParticipant; _hasPersistenceModule = extensionManager.HasSingletonPersistenceModule; // create an uber-IEnumerable to simplify our iteration code _allSingletonExtensions = _extensionManager.GetAllSingletonExtensions(); } else { _allSingletonExtensions = WorkflowInstanceExtensionManager.EmptySingletonExtensions; } // Resolve activity extensions Dictionary <Type, WorkflowInstanceExtensionProvider> activityExtensionProviders; Dictionary <Type, WorkflowInstanceExtensionProvider> filteredActivityExtensionProviders = null; HashSet <Type> requiredActivityExtensionTypes; if (workflowDefinition.GetActivityExtensionInformation(out activityExtensionProviders, out requiredActivityExtensionTypes)) { // a) filter out the extension Types that were already configured by the host. Note that only "primary" extensions are in play here, not // "additional" extensions HashSet <Type> allExtensionTypes = new HashSet <Type>(); if (extensionManager != null) { extensionManager.AddAllExtensionTypes(allExtensionTypes); } if (activityExtensionProviders != null) { filteredActivityExtensionProviders = new Dictionary <Type, WorkflowInstanceExtensionProvider>(activityExtensionProviders.Count); foreach (KeyValuePair <Type, WorkflowInstanceExtensionProvider> keyedActivityExtensionProvider in activityExtensionProviders) { Type newExtensionProviderType = keyedActivityExtensionProvider.Key; if (!TypeHelper.ContainsCompatibleType(allExtensionTypes, newExtensionProviderType)) { // first see if the new provider supersedes any existing ones List <Type> typesToRemove = null; bool skipNewExtensionProvider = false; foreach (Type existingExtensionProviderType in filteredActivityExtensionProviders.Keys) { // Use AreReferenceTypesCompatible for performance since we know that all of these must be reference types if (TypeHelper.AreReferenceTypesCompatible(existingExtensionProviderType, newExtensionProviderType)) { skipNewExtensionProvider = true; break; } if (TypeHelper.AreReferenceTypesCompatible(newExtensionProviderType, existingExtensionProviderType)) { if (typesToRemove == null) { typesToRemove = new List <Type>(); } typesToRemove.Add(existingExtensionProviderType); } } // prune unnecessary extension providers (either superseded by the new extension or by an existing extension that supersedes them both) if (typesToRemove != null) { for (int i = 0; i < typesToRemove.Count; i++) { filteredActivityExtensionProviders.Remove(typesToRemove[i]); } } // and add a new extension if necessary if (!skipNewExtensionProvider) { filteredActivityExtensionProviders.Add(newExtensionProviderType, keyedActivityExtensionProvider.Value); } } } if (filteredActivityExtensionProviders.Count > 0) { allExtensionTypes.UnionWith(filteredActivityExtensionProviders.Keys); extensionProviderCount += filteredActivityExtensionProviders.Count; } } // b) Validate that all required extensions will be provided if (requiredActivityExtensionTypes != null && requiredActivityExtensionTypes.Count > 0) { foreach (Type requiredType in requiredActivityExtensionTypes) { if (!TypeHelper.ContainsCompatibleType(allExtensionTypes, requiredType)) { throw CoreWf.Internals.FxTrace.Exception.AsError(new ValidationException(SR.RequiredExtensionTypeNotFound(requiredType.ToString()))); } } } } // Finally, if our checks of passed, resolve our delegates if (extensionProviderCount > 0) { _instanceExtensions = new List <KeyValuePair <WorkflowInstanceExtensionProvider, object> >(extensionProviderCount); if (extensionManager != null) { List <KeyValuePair <Type, WorkflowInstanceExtensionProvider> > extensionProviders = extensionManager.ExtensionProviders; for (int i = 0; i < extensionProviders.Count; i++) { KeyValuePair <Type, WorkflowInstanceExtensionProvider> extensionProvider = extensionProviders[i]; AddInstanceExtension(extensionProvider.Value); } } if (filteredActivityExtensionProviders != null) { foreach (WorkflowInstanceExtensionProvider extensionProvider in filteredActivityExtensionProviders.Values) { AddInstanceExtension(extensionProvider); } } } }