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
- RowUpdatedEventArgs.cs
- KnownAssembliesSet.cs
- Soap.cs
- WebZone.cs
- TreeView.cs
- ToolboxItemAttribute.cs
- VectorCollectionValueSerializer.cs
- PtsHost.cs
- ColorMatrix.cs
- SemanticBasicElement.cs
- RayMeshGeometry3DHitTestResult.cs
- ElementProxy.cs
- BindingWorker.cs
- arabicshape.cs
- RequestUriProcessor.cs
- MailDefinition.cs
- EventListenerClientSide.cs
- ProfileService.cs
- ShaderEffect.cs
- PropertyDescriptorCollection.cs
- OdbcException.cs
- MetadataPropertyvalue.cs
- InvalidComObjectException.cs
- ToolStripDropDownClosedEventArgs.cs
- DispatcherExceptionFilterEventArgs.cs
- BoolExpr.cs
- DataSourceControl.cs
- SchemaElementDecl.cs
- NativeMethods.cs
- MenuEventArgs.cs
- LoginView.cs
- StandardTransformFactory.cs
- StorageTypeMapping.cs
- GrammarBuilderPhrase.cs
- DatasetMethodGenerator.cs
- CommonXSendMessage.cs
- SqlStatistics.cs
- ExpressionEditorAttribute.cs
- ToolBar.cs
- UnsignedPublishLicense.cs
- ImageFormatConverter.cs
- _RegBlobWebProxyDataBuilder.cs
- XamlSerializerUtil.cs
- WindowsListViewGroupSubsetLink.cs
- DynamicPropertyHolder.cs
- Parser.cs
- IntPtr.cs
- BadImageFormatException.cs
- RoamingStoreFile.cs
- X509Certificate2Collection.cs
- MonthCalendarDesigner.cs
- FormViewUpdateEventArgs.cs
- TreeNodeEventArgs.cs
- Errors.cs
- GlobalizationSection.cs
- CategoryAttribute.cs
- SingleConverter.cs
- TableItemStyle.cs
- TransformGroup.cs
- WebServiceBindingAttribute.cs
- CodeComment.cs
- WebPartZoneCollection.cs
- CommonObjectSecurity.cs
- GeneralTransform2DTo3D.cs
- ToolCreatedEventArgs.cs
- LineSegment.cs
- MatrixUtil.cs
- UserControlCodeDomTreeGenerator.cs
- _ChunkParse.cs
- IdentitySection.cs
- ModelPropertyDescriptor.cs
- HatchBrush.cs
- MaskedTextProvider.cs
- MimeTypeAttribute.cs
- CommandValueSerializer.cs
- DesignTimeHTMLTextWriter.cs
- ListView.cs
- Stack.cs
- PixelFormatConverter.cs
- GridView.cs
- SecurityElement.cs
- ConsoleTraceListener.cs
- DisplayInformation.cs
- Decorator.cs
- MultiBindingExpression.cs
- _NegoState.cs
- securitycriticaldata.cs
- ProcessInfo.cs
- WCFBuildProvider.cs
- SqlProcedureAttribute.cs
- EmptyEnumerator.cs
- StreamHelper.cs
- XmlTextAttribute.cs
- WebServiceParameterData.cs
- ReadOnlyAttribute.cs
- NotifyParentPropertyAttribute.cs
- StagingAreaInputItem.cs
- XmlArrayItemAttribute.cs
- FontFamilyIdentifier.cs
- JsonWriter.cs