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
- BaseTemplateCodeDomTreeGenerator.cs
- SmtpNtlmAuthenticationModule.cs
- DNS.cs
- EventHandlerList.cs
- ToolStripSettings.cs
- WindowInteractionStateTracker.cs
- XmlSchemaAll.cs
- ToolStripContainer.cs
- Missing.cs
- MailDefinition.cs
- ProviderUtil.cs
- CallbackCorrelationInitializer.cs
- panel.cs
- MemberAssignment.cs
- WindowsImpersonationContext.cs
- XmlNodeComparer.cs
- ZipQueryOperator.cs
- Pair.cs
- PolicyManager.cs
- Clause.cs
- InfoCardProofToken.cs
- TextServicesHost.cs
- FontDialog.cs
- PolyLineSegment.cs
- TextDecorationUnitValidation.cs
- OleDbDataReader.cs
- RSACryptoServiceProvider.cs
- HttpInputStream.cs
- DataRelation.cs
- ListViewItemEventArgs.cs
- TrustLevel.cs
- Compiler.cs
- DataRowChangeEvent.cs
- WriteLineDesigner.xaml.cs
- InvokePatternIdentifiers.cs
- ImageKeyConverter.cs
- ProjectedWrapper.cs
- ProgressPage.cs
- TextFormatterContext.cs
- Events.cs
- MediaPlayer.cs
- EventLogTraceListener.cs
- BaseProcessProtocolHandler.cs
- StyleXamlParser.cs
- ReachUIElementCollectionSerializer.cs
- CancelRequestedRecord.cs
- TypeToArgumentTypeConverter.cs
- hresults.cs
- Slider.cs
- StrokeCollectionDefaultValueFactory.cs
- TextPointer.cs
- CacheOutputQuery.cs
- DocumentViewerConstants.cs
- UInt16.cs
- QilReplaceVisitor.cs
- PageWrapper.cs
- WebServicesInteroperability.cs
- WindowsAltTab.cs
- compensatingcollection.cs
- ResourceManager.cs
- QueuePathDialog.cs
- ResourceAssociationSetEnd.cs
- DataException.cs
- Rect3DConverter.cs
- BindingBase.cs
- SQLDateTimeStorage.cs
- ColorTranslator.cs
- SaveFileDialog.cs
- StdValidatorsAndConverters.cs
- TypeSystem.cs
- WeakReferenceList.cs
- UIElementHelper.cs
- CodeAttachEventStatement.cs
- ContentWrapperAttribute.cs
- AnnotationHighlightLayer.cs
- AtlasWeb.Designer.cs
- DynamicValidatorEventArgs.cs
- SizeLimitedCache.cs
- CodeDomSerializerBase.cs
- RectAnimationBase.cs
- CustomPopupPlacement.cs
- SpecialFolderEnumConverter.cs
- MetadataUtilsSmi.cs
- ManipulationDevice.cs
- COM2EnumConverter.cs
- Style.cs
- _SecureChannel.cs
- DBCSCodePageEncoding.cs
- QilParameter.cs
- CodeGenHelper.cs
- SoapCodeExporter.cs
- ListChunk.cs
- XmlDataSourceView.cs
- FullTrustAssemblyCollection.cs
- WorkBatch.cs
- TraceUtils.cs
- HostedHttpTransportManager.cs
- TemplateBindingExpressionConverter.cs
- CodeAttributeArgument.cs
- DbgUtil.cs