Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.ServiceModel.Activities / System / ServiceModel / Activities / WorkflowService.cs / 1480445 / WorkflowService.cs
//---------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //--------------------------------------------------------------- namespace System.ServiceModel.Activities { using System.Activities; using System.Activities.Debugger; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime; using System.ServiceModel.Activities.Description; using System.ServiceModel.Description; using System.ServiceModel.XamlIntegration; using System.Windows.Markup; using System.Xml; using System.Xml.Linq; [ContentProperty("Body")] public class WorkflowService : IDebuggableWorkflowTree { Collectionendpoints; IDictionary cachedInferredContracts; IDictionary > correlationQueryByContract; IList knownServiceActivities; HashSet receiveAndReplyPairs; ServiceDescription serviceDescription; XName inferedServiceName; public WorkflowService() { } [DefaultValue(null)] public Activity Body { get; set; } [Fx.Tag.KnownXamlExternal] [DefaultValue(null)] [TypeConverter(typeof(ServiceXNameTypeConverter))] public XName Name { get; set; } [DefaultValue(null)] public string ConfigurationName { get; set; } [DefaultValue(false)] public bool AllowBufferedReceive { get; set; } public Collection Endpoints { get { if (this.endpoints == null) { this.endpoints = new Collection (); } return this.endpoints; } } internal XName InternalName { get { if (this.Name != null) { return this.Name; } else { if (this.inferedServiceName == null) { Fx.Assert(this.Body != null, "Body cannot be null!"); if (this.Body.DisplayName.Length == 0) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.MissingDisplayNameInRootActivity)); } this.inferedServiceName = XName.Get(XmlConvert.EncodeLocalName(this.Body.DisplayName)); } return this.inferedServiceName; } } } internal IDictionary > CorrelationQueries { get { Fx.Assert(this.cachedInferredContracts != null, "Must infer contract first!"); return this.correlationQueryByContract; } } public Activity GetWorkflowRoot() { return this.Body; } internal ServiceDescription GetEmptyServiceDescription() { if (this.serviceDescription == null) { WalkActivityTree(); ServiceDescription result = new ServiceDescription { Name = this.InternalName.LocalName, Namespace = string.IsNullOrEmpty(this.InternalName.NamespaceName) ? NamingHelper.DefaultNamespace : this.InternalName.NamespaceName, ConfigurationName = this.ConfigurationName ?? this.InternalName.LocalName }; result.Behaviors.Add(new WorkflowServiceBehavior(this.Body)); this.serviceDescription = result; } return this.serviceDescription; } internal IDictionary GetContractDescriptions() { if (this.cachedInferredContracts == null) { WalkActivityTree(); Fx.Assert(this.knownServiceActivities != null && this.receiveAndReplyPairs != null, "Failed to walk the activity tree!"); this.correlationQueryByContract = new Dictionary >(); // Contract inference IDictionary inferredContracts = new Dictionary (); IDictionary keyedByNameOperationInfo = new Dictionary (); foreach (Receive receive in this.knownServiceActivities) { XName contractXName = FixServiceContractName(receive.ServiceContractName); ContractAndOperationNameTuple tuple = new ContractAndOperationNameTuple(contractXName, receive.OperationName); OperationInfo operationInfo; if (keyedByNameOperationInfo.TryGetValue(tuple, out operationInfo)) { // All Receives with same ServiceContractName and OperationName need to be validated ContractValidationHelper.ValidateReceiveWithReceive(receive, operationInfo.Receive); } else { // Note that activities in keyedByNameOperationInfo are keyed by // ServiceContractName and OperationName tuple. So we won't run into the case where // two opertions have the same OperationName. ContractDescription contract; if (!inferredContracts.TryGetValue(contractXName, out contract)) { // Infer Name, Namespace contract = new ContractDescription(contractXName.LocalName, contractXName.NamespaceName); // We use ServiceContractName.LocalName to bind contract with config contract.ConfigurationName = contractXName.LocalName; // We do NOT infer ContractDescription.ProtectionLevel inferredContracts.Add(contractXName, contract); } OperationDescription operation = ContractInferenceHelper.CreateOperationDescription(receive, contract); contract.Operations.Add(operation); operationInfo = new OperationInfo(receive, operation); keyedByNameOperationInfo.Add(tuple, operationInfo); } CorrectOutMessageForOperationWithFault(receive, operationInfo); ContractInferenceHelper.UpdateIsOneWayFlag(receive, operationInfo.OperationDescription); // FaultTypes and KnownTypes need to be collected from all Receive activities ContractInferenceHelper.AddFaultDescription(receive, operationInfo.OperationDescription); ContractInferenceHelper.AddKnownTypesToOperation(receive, operationInfo.OperationDescription); // WorkflowFormatterBehavior should have reference to all the Receive activities ContractInferenceHelper.AddReceiveToFormatterBehavior(receive, operationInfo.OperationDescription); Collection correlationQueries = null; // Collect CorrelationQuery from Receive if (receive.HasCorrelatesOn || receive.HasCorrelationInitializers) { MessageQuerySet select = receive.HasCorrelatesOn ? receive.CorrelatesOn : null; CorrelationQuery correlationQuery = ContractInferenceHelper.CreateServerCorrelationQuery(select, receive.CorrelationInitializers, operationInfo.OperationDescription, false); CollectCorrelationQuery(ref correlationQueries, contractXName, correlationQuery); } // Find all known Receive-Reply pair in the activity tree. Remove them from this.receiveAndReplyPairs // Also collect CorrelationQuery from following replies if (receive.HasReply) { foreach (SendReply reply in receive.FollowingReplies) { ReceiveAndReplyTuple pair = new ReceiveAndReplyTuple(receive, reply); this.receiveAndReplyPairs.Remove(pair); CollectCorrelationQueryFromReply(ref correlationQueries, contractXName, reply, operationInfo.OperationDescription); reply.SetContractName(contractXName); } } if (receive.HasFault) { foreach (Activity fault in receive.FollowingFaults) { ReceiveAndReplyTuple pair = new ReceiveAndReplyTuple(receive, fault); this.receiveAndReplyPairs.Remove(pair); CollectCorrelationQueryFromReply(ref correlationQueries, contractXName, fault, operationInfo.OperationDescription); } } } // Check for Receive referenced by SendReply but no longer in the activity tree if (this.receiveAndReplyPairs.Count != 0) { throw FxTrace.Exception.AsError(new ValidationException(SR.DanglingReceive)); } // Print out tracing information if (TD.InferredContractDescriptionIsEnabled()) { foreach (ContractDescription contract in inferredContracts.Values) { TD.InferredContractDescription(contract.Name, contract.Namespace); if (TD.InferredOperationDescriptionIsEnabled()) { foreach (OperationDescription operation in contract.Operations) { TD.InferredOperationDescription(operation.Name, contract.Name, operation.IsOneWay.ToString()); } } } } this.cachedInferredContracts = inferredContracts; } return this.cachedInferredContracts; } void WalkActivityTree() { if (this.knownServiceActivities != null) { // We return if we have already walked the activity tree return; } if (this.Body == null) { throw FxTrace.Exception.AsError(new ValidationException(SR.MissingBodyInWorkflowService)); } // Validate the activity tree WorkflowInspectionServices.CacheMetadata(this.Body); this.knownServiceActivities = new List (); this.receiveAndReplyPairs = new HashSet (); // Now let us walk the tree here Queue activities = new Queue (); // The root activity is never "in" a TransactedReceiveScope activities.Enqueue(new QueueItem(this.Body, null, null)); while (activities.Count > 0) { QueueItem queueItem = activities.Dequeue(); Fx.Assert(queueItem != null, "Queue item cannot be null"); Activity activity = queueItem.Activity; Fx.Assert(queueItem.Activity != null, "Queue item's Activity cannot be null"); TransactedReceiveScope transactedReceiveScope = queueItem.ParentTransactedReceiveScope; TransactedReceiveScope rootTransactedReceiveScope = queueItem.RootTransactedReceiveScope; if (activity is Receive) // First, let's see if this is a Receive activity { Receive receive = (Receive)activity; if (rootTransactedReceiveScope != null) { receive.InternalReceive.AdditionalData.IsInsideTransactedReceiveScope = true; Fx.Assert(transactedReceiveScope != null, "Internal error.. TransactedReceiveScope should be valid here"); if ((receive == transactedReceiveScope.Request) && (transactedReceiveScope == rootTransactedReceiveScope)) { receive.InternalReceive.AdditionalData.IsFirstReceiveOfTransactedReceiveScopeTree = true; } } this.knownServiceActivities.Add(receive); } else if (activity is SendReply) // Let's see if this is a SendReply { SendReply sendReply = (SendReply)activity; Receive pairedReceive = sendReply.Request; Fx.Assert(pairedReceive != null, "SendReply must point to a Receive!"); if (sendReply.InternalContent.IsFault) { pairedReceive.FollowingFaults.Add(sendReply); } else { if (pairedReceive.HasReply) { SendReply followingReply = pairedReceive.FollowingReplies[0]; ContractValidationHelper.ValidateSendReplyWithSendReply(followingReply, sendReply); } pairedReceive.FollowingReplies.Add(sendReply); } ReceiveAndReplyTuple tuple = new ReceiveAndReplyTuple(pairedReceive, sendReply); this.receiveAndReplyPairs.Add(tuple); } // Enqueue child activities and delegates if (activity is TransactedReceiveScope) { transactedReceiveScope = activity as TransactedReceiveScope; if (rootTransactedReceiveScope == null) { rootTransactedReceiveScope = transactedReceiveScope; } } foreach (Activity childActivity in WorkflowInspectionServices.GetActivities(activity)) { QueueItem queueData = new QueueItem(childActivity, transactedReceiveScope, rootTransactedReceiveScope); activities.Enqueue(queueData); } } } XName FixServiceContractName(XName serviceContractName) { // By default, we use WorkflowService.Name as ServiceContractName XName contractXName = serviceContractName ?? this.InternalName; ContractInferenceHelper.ProvideDefaultNamespace(ref contractXName); return contractXName; } void CorrectOutMessageForOperationWithFault(Receive receive, OperationInfo operationInfo) { Fx.Assert(receive != null && operationInfo != null, "Argument cannot be null!"); Receive prevReceive = operationInfo.Receive; if (receive != prevReceive && receive.HasReply && !prevReceive.HasReply && prevReceive.HasFault) { ContractInferenceHelper.CorrectOutMessageForOperation(receive, operationInfo.OperationDescription); operationInfo.Receive = receive; } } void CollectCorrelationQuery(ref Collection queries, XName serviceContractName, CorrelationQuery correlationQuery) { Fx.Assert(serviceContractName != null, "Argument cannot be null!"); if (correlationQuery == null) { return; } if (queries == null && !this.correlationQueryByContract.TryGetValue(serviceContractName, out queries)) { queries = new Collection (); this.correlationQueryByContract.Add(serviceContractName, queries); } queries.Add(correlationQuery); } void CollectCorrelationQueryFromReply(ref Collection correlationQueries, XName serviceContractName, Activity reply, OperationDescription operation) { SendReply sendReply = reply as SendReply; if (sendReply != null) { CorrelationQuery correlationQuery = ContractInferenceHelper.CreateServerCorrelationQuery( null, sendReply.CorrelationInitializers, operation, true); CollectCorrelationQuery(ref correlationQueries, serviceContractName, correlationQuery); } } internal void ResetServiceDescription() { this.serviceDescription = null; this.cachedInferredContracts = null; } struct ContractAndOperationNameTuple { XName ServiceContractXName; string OperationName; public ContractAndOperationNameTuple(XName serviceContractXName, string operationName) { this.ServiceContractXName = serviceContractXName; this.OperationName = operationName; } } struct ReceiveAndReplyTuple { Receive Receive; Activity Reply; public ReceiveAndReplyTuple(Receive receive, Activity reply) { this.Receive = receive; this.Reply = reply; } } class OperationInfo { Receive receive; OperationDescription operationDescription; public OperationInfo(Receive receive, OperationDescription operationDescription) { this.receive = receive; this.operationDescription = operationDescription; } public Receive Receive { get { return this.receive; } set { this.receive = value; } } public OperationDescription OperationDescription { get { return this.operationDescription; } } } class QueueItem { Activity activity; TransactedReceiveScope parent; TransactedReceiveScope rootTransactedReceiveScope; public QueueItem(Activity element, TransactedReceiveScope parent, TransactedReceiveScope rootTransactedReceiveScope) { this.activity = element; this.parent = parent; this.rootTransactedReceiveScope = rootTransactedReceiveScope; } public Activity Activity { get { return this.activity; } } public TransactedReceiveScope ParentTransactedReceiveScope { get { return this.parent; } } public TransactedReceiveScope RootTransactedReceiveScope { get { return this.rootTransactedReceiveScope; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HttpConfigurationSystem.cs
- XmlAnyElementAttribute.cs
- ChtmlTextWriter.cs
- newinstructionaction.cs
- SafeProcessHandle.cs
- UnsafeNativeMethods.cs
- OracleBoolean.cs
- FixedTextView.cs
- MatrixUtil.cs
- ComponentChangedEvent.cs
- HttpRuntimeSection.cs
- UnsafeNativeMethods.cs
- FactoryId.cs
- XmlCharCheckingReader.cs
- DateTimeOffsetAdapter.cs
- SchemaElementDecl.cs
- UserMapPath.cs
- WindowsScrollBar.cs
- QueryStringParameter.cs
- CustomValidator.cs
- ExpressionPrinter.cs
- StyleCollection.cs
- UdpConstants.cs
- DbMetaDataFactory.cs
- EntityDesignerBuildProvider.cs
- PieceDirectory.cs
- _LocalDataStoreMgr.cs
- DbProviderSpecificTypePropertyAttribute.cs
- CodeDOMProvider.cs
- PersonalizationStateQuery.cs
- SelectionChangedEventArgs.cs
- BlobPersonalizationState.cs
- SafeNativeMethods.cs
- BindToObject.cs
- PolicyUtility.cs
- LocalizationComments.cs
- SystemException.cs
- RoleService.cs
- AttachedPropertyBrowsableForChildrenAttribute.cs
- cookiecontainer.cs
- LocalizationParserHooks.cs
- AstNode.cs
- ErrorProvider.cs
- HeaderedItemsControl.cs
- NetSectionGroup.cs
- CssStyleCollection.cs
- ModuleElement.cs
- SiteIdentityPermission.cs
- HuffCodec.cs
- IsolatedStorageFilePermission.cs
- OrElse.cs
- HttpPostedFile.cs
- __ConsoleStream.cs
- ViewRendering.cs
- PageThemeBuildProvider.cs
- DbProviderConfigurationHandler.cs
- ScriptControl.cs
- Util.cs
- ListenerElementsCollection.cs
- PrintDialog.cs
- StateManagedCollection.cs
- XsdCachingReader.cs
- ToolStripItemCollection.cs
- VirtualizedItemPattern.cs
- AssociationSetEnd.cs
- VisualBasicReference.cs
- BrowserDefinition.cs
- ClientBuildManagerCallback.cs
- DataGridViewColumnConverter.cs
- DoubleLink.cs
- TraceData.cs
- DataGridViewAccessibleObject.cs
- SecurityHelper.cs
- OleDbTransaction.cs
- FormatterConverter.cs
- HtmlDocument.cs
- WindowsRegion.cs
- PeerValidationBehavior.cs
- RSAPKCS1SignatureDeformatter.cs
- TemplatedMailWebEventProvider.cs
- TypedAsyncResult.cs
- TreeBuilderXamlTranslator.cs
- DataProviderNameConverter.cs
- DiscardableAttribute.cs
- WebRequestModuleElement.cs
- CachedFontFace.cs
- controlskin.cs
- ChtmlTextWriter.cs
- ObjectQueryProvider.cs
- StringCollectionMarkupSerializer.cs
- QueryTreeBuilder.cs
- DataSpaceManager.cs
- TemplatePropertyEntry.cs
- TypeLibConverter.cs
- DataServiceRequest.cs
- RoutingChannelExtension.cs
- InputDevice.cs
- TextEditorThreadLocalStore.cs
- AssemblyFilter.cs
- ObjectItemCollectionAssemblyCacheEntry.cs