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
- WebReferencesBuildProvider.cs
- PasswordRecovery.cs
- Command.cs
- EditingMode.cs
- ExtendedPropertyDescriptor.cs
- ApplicationManager.cs
- ApplyImportsAction.cs
- DataKeyCollection.cs
- QueryContinueDragEventArgs.cs
- BitSet.cs
- DoWorkEventArgs.cs
- MappedMetaModel.cs
- GradientSpreadMethodValidation.cs
- SspiWrapper.cs
- PackagingUtilities.cs
- XmlUnspecifiedAttribute.cs
- DynamicEntity.cs
- Cell.cs
- WebScriptEnablingElement.cs
- BaseAddressElement.cs
- SafeIUnknown.cs
- ViewStateModeByIdAttribute.cs
- BinaryFormatterWriter.cs
- XmlnsDefinitionAttribute.cs
- PrinterUnitConvert.cs
- CollectionViewGroup.cs
- GridView.cs
- HttpApplication.cs
- PersonalizableTypeEntry.cs
- ClosureBinding.cs
- UInt16Storage.cs
- ZoomPercentageConverter.cs
- Bezier.cs
- DbConnectionStringBuilder.cs
- EditorPartCollection.cs
- GregorianCalendar.cs
- DrawingCollection.cs
- HtmlControlAdapter.cs
- ExecutedRoutedEventArgs.cs
- configsystem.cs
- MD5.cs
- ControlPaint.cs
- CopyOfAction.cs
- PermissionAttributes.cs
- Transform.cs
- ListItemConverter.cs
- FixedTextPointer.cs
- IPHostEntry.cs
- SelectionRangeConverter.cs
- GorillaCodec.cs
- RegexParser.cs
- Encoder.cs
- CustomActivityDesigner.cs
- CheckPair.cs
- EmbeddedMailObjectsCollection.cs
- HtmlForm.cs
- SafeHandles.cs
- ProcessProtocolHandler.cs
- PerformanceCounterPermissionEntry.cs
- TimeSpanMinutesOrInfiniteConverter.cs
- DoubleLink.cs
- CryptoKeySecurity.cs
- MailDefinition.cs
- Form.cs
- WebHttpEndpoint.cs
- SmiMetaData.cs
- HtmlForm.cs
- storepermission.cs
- Command.cs
- DataGridViewCellStateChangedEventArgs.cs
- CodeDomSerializationProvider.cs
- XMLUtil.cs
- EventSetter.cs
- PathData.cs
- SqlXmlStorage.cs
- SqlDataRecord.cs
- RawMouseInputReport.cs
- DataGridViewIntLinkedList.cs
- BinaryParser.cs
- FileVersionInfo.cs
- WebPartConnectionsDisconnectVerb.cs
- CacheDependency.cs
- FormClosingEvent.cs
- TypefaceCollection.cs
- HttpWebResponse.cs
- SequenceNumber.cs
- OrderedHashRepartitionStream.cs
- MethodCallConverter.cs
- ResXResourceWriter.cs
- StrokeNode.cs
- SourceFileBuildProvider.cs
- CalendarTable.cs
- BrowserDefinition.cs
- WCFModelStrings.Designer.cs
- HttpConfigurationContext.cs
- BoundField.cs
- RegistrationServices.cs
- DirectionalAction.cs
- XpsFilter.cs
- SqlIdentifier.cs