static Activity GetServiceWorkflow() { Variable<string> echoString = new Variable<string>(); Receive echoRequest = new Receive { CanCreateInstance = true, ServiceContractName = contract, OperationName = "Echo", Content = new ReceiveParametersContent() { Parameters = { { "echoString", new OutArgument<string>(echoString) } } } }; return new ReceiveInstanceIdScope { Variables = { echoString }, Activities = { echoRequest, new WriteLine { Text = new InArgument<string>( (e) => "Received: " + echoString.Get(e) ) }, new SendReply { Request = echoRequest, Content = new SendParametersContent() { Parameters = { { "result", new InArgument<string>(echoString) } } } } } }; }
private Activity InternalImplementation() { Receive receive = new Receive { OperationName = "DoRequestReply", CanCreateInstance = true, ServiceContractName = XName.Get("ISuppressSample", "http://tempuri.org/"), }; return new Sequence { Activities = { new TransactedReceiveScope { Request = receive, Body = new Sequence { Activities = { //If the distributed ID does not match that which is printed out on the client, then it was // created locally on the server and no transaction was flowed by the client. new PrintTxID(), new SendReply { Request = receive, }, }, }, }, }, }; }
private static WorkflowService CreateService() { Variable<string> message = new Variable<string> { Name = "message" }; Receive receiveString = new Receive { OperationName = "Print", ServiceContractName = XName.Get("IPrintService", "http://tempuri.org/"), Content = new ReceiveParametersContent { Parameters = { {"message", new OutArgument<string>(message)} } }, CanCreateInstance = true }; Sequence workflow = new Sequence() { Variables = { message }, Activities = { receiveString, new WriteLine { Text = new InArgument<string>(env =>("Message received from Client: " + message.Get(env))) }, }, }; return new WorkflowService { Name = "PrintService", Body = workflow }; }
private static void CreateService() { Variable<string> message = new Variable<string> { Name = "message" }; Variable<string> echo = new Variable<string> { Name = "echo" }; Receive receiveString = new Receive { OperationName = "Echo", ServiceContractName = "Echo", CanCreateInstance = true, //parameters for receive Content = new ReceiveParametersContent { Parameters = { {"message", new OutArgument<string>(message)} } } }; Sequence workflow = new Sequence() { Variables = { message, echo }, Activities = { receiveString, new WriteLine { Text = new InArgument<string>(env =>("Message received: " + message.Get(env))) }, new Assign<string> { Value = new InArgument<string>(env =>("<echo> " + message.Get(env))), To = new OutArgument<string>(echo) }, //parameters for reply new SendReply { Request = receiveString, Content = new SendParametersContent { Parameters = { { "echo", new InArgument<string>(echo) } }, } }, new WriteLine { Text = new InArgument<string>(env =>("Message sent: " + echo.Get(env))) }, }, }; service = new WorkflowService { Name = "Echo", Body = workflow }; }
private void CorrectOutMessageForOperationWithFault(Receive receive, OperationInfo operationInfo) { Receive receive2 = operationInfo.Receive; if (((receive != receive2) && receive.HasReply) && (!receive2.HasReply && receive2.HasFault)) { ContractInferenceHelper.CorrectOutMessageForOperation(receive, operationInfo.OperationDescription); operationInfo.Receive = receive; } }
private Activity InternalImplementation() { Variable<string> requestMessage = new Variable<string> { Name = "requestString" }; Variable<string> replyMessage = new Variable<string> { Name = "replyString" }; Receive receive = new Receive { OperationName = "StartSample", CanCreateInstance = true, Content = ReceiveContent.Create(new OutArgument<string>(requestMessage)), ServiceContractName = "ITransactedReceiveService", }; return new Sequence { Activities = { new WriteLine { Text = "Service workflow begins." }, new System.ServiceModel.Activities.TransactedReceiveScope { Variables = { requestMessage, replyMessage }, Request = receive, Body = new Sequence { Activities = { new WriteLine { Text = new InArgument<string>("Server side: Receive complete.") }, new WriteLine { Text = new InArgument<string>(new VisualBasicValue<string>() { ExpressionText = "\"Server side: Received = '\" + requestString.toString() + \"'\"" }) }, new PrintTransactionInfo(), new Assign<string> { Value = new InArgument<string>("Server side: Sending reply."), To = new OutArgument<string>(replyMessage) }, new WriteLine { Text = new InArgument<string>("Server side: Begin reply.") }, new SendReply { Request = receive, Content = SendContent.Create(new InArgument<string>(replyMessage)), }, new WriteLine { Text = new InArgument<string>("Server side: Reply sent.") }, }, }, }, new WriteLine { Text = "Server workflow ends." }, }, }; }
public OperationScope() : base() { assigns = new Collection<Assign>(); variables = new Collection<Variable>(); receive = new Receive() { Content = new ReceiveParametersContent() }; reply = new SendReply() { Request = receive, Content = new SendParametersContent() }; }
public static void AddFaultDescription(Receive activity, OperationDescription operation) { if (activity.HasFault) { foreach (SendReply reply in activity.FollowingFaults) { string overridingAction = null; System.Type internalDeclaredMessageType = null; overridingAction = reply.Action; SendMessageContent internalContent = reply.InternalContent as SendMessageContent; if (internalContent != null) { internalDeclaredMessageType = internalContent.InternalDeclaredMessageType; } else { SendParametersContent content2 = reply.InternalContent as SendParametersContent; if (content2 != null) { internalDeclaredMessageType = content2.ArgumentTypes[0]; } } if (internalDeclaredMessageType.IsGenericType && (internalDeclaredMessageType.GetGenericTypeDefinition() == FaultExceptionType)) { System.Type faultType = internalDeclaredMessageType.GetGenericArguments()[0]; bool flag = false; foreach (FaultDescription description in operation.Faults) { if (description.DetailType == faultType) { if (description.Action != overridingAction) { throw System.ServiceModel.Activities.FxTrace.Exception.AsError(new ValidationException(System.ServiceModel.Activities.SR.SendRepliesHaveSameFaultTypeDifferentAction)); } flag = true; break; } } if (!flag) { FaultDescription item = MessageBuilder.CreateFaultDescription(operation, faultType, overridingAction); operation.Faults.Add(item); } } } } }
public static void ValidateReceiveWithReceive(Receive receive1, Receive receive2) { Fx.Assert(receive1 != null && receive2 != null, "Validation argument cannot be null!"); Fx.Assert(receive1.OperationName != null, "OperationName cannot be null in Receive"); string receiveOperationName = receive1.OperationName; if (receive1.Action != receive2.Action) { throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoReceivesWithSameNameButDifferentAction(receiveOperationName))); } if (receive1.InternalContent is ReceiveMessageContent && receive2.InternalContent is ReceiveMessageContent) { ReceiveMessageContent receiveMessage1 = receive1.InternalContent as ReceiveMessageContent; ReceiveMessageContent receiveMessage2 = receive2.InternalContent as ReceiveMessageContent; ValidateReceiveWithReceive(receiveMessage1, receiveMessage2, receiveOperationName); } else if (receive1.InternalContent is ReceiveParametersContent && receive2.InternalContent is ReceiveParametersContent) { ReceiveParametersContent receiveParameters1 = receive1.InternalContent as ReceiveParametersContent; ReceiveParametersContent receiveParameters2 = receive2.InternalContent as ReceiveParametersContent; ValidateReceiveParametersWithReceiveParameters(receiveParameters1, receiveParameters2, receiveOperationName); } else { throw FxTrace.Exception.AsError(new ValidationException(SR2.ReceiveAndReceiveParametersHaveSameName(receiveOperationName))); } if (receive1.HasReply && receive2.HasReply) { ValidateSendReplyWithSendReply(receive1.FollowingReplies[0], receive2.FollowingReplies[0]); } else if ((receive1.HasReply || receive1.HasFault) != (receive2.HasReply || receive2.HasFault)) { throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoReceivesWithSameNameButDifferentIsOneWay(receiveOperationName))); } if ((receive1.InternalReceive.AdditionalData.IsInsideTransactedReceiveScope != receive2.InternalReceive.AdditionalData.IsInsideTransactedReceiveScope) || (receive1.InternalReceive.AdditionalData.IsFirstReceiveOfTransactedReceiveScopeTree != receive2.InternalReceive.AdditionalData.IsFirstReceiveOfTransactedReceiveScopeTree)) { throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoReceivesWithSameNameButDifferentTxProperties(receiveOperationName))); } }
static WorkflowService GetService() { Variable<string> incomingMessage = new Variable<string> { Name = "inmessage" }; Variable<int> outgoingMessage = new Variable<int> { Name = "outmessage" }; Receive receiveSecureData = new Receive { OperationName = "AskQuestion", ServiceContractName = "ISecuredService", CanCreateInstance = true, Content = ReceiveContent.Create(new OutArgument<string>(incomingMessage)) }; Sequence SecuredWorkFlow = new Sequence() { Variables = { incomingMessage, outgoingMessage }, Activities = { receiveSecureData, new WriteLine { Text = new InArgument<string>(env =>("Message received: " + incomingMessage.Get(env))) }, new SendReply { Request = receiveSecureData, Content = SendContent.Create(new InArgument<int>(4)) } } }; WorkflowService service = new WorkflowService { Name = "SecuredService", Body = SecuredWorkFlow, ConfigurationName = "SecuredService" }; return service; }
public Activity Create(DependencyObject target) { string correlationHandleName = ActivityDesignerHelper.GenerateUniqueVariableNameForContext(target, correlationHandleNamePrefix); Variable<CorrelationHandle> requestReplyCorrelation = new Variable<CorrelationHandle> { Name = correlationHandleName }; Receive receive = new Receive { OperationName = "Operation1", ServiceContractName = XName.Get("IService", "http://tempuri.org/"), CorrelationInitializers = { new RequestReplyCorrelationInitializer { CorrelationHandle = new VariableValue<CorrelationHandle> { Variable = requestReplyCorrelation } } } }; Sequence sequence = new Sequence() { Variables = { requestReplyCorrelation }, Activities = { receive, new SendReply { DisplayName = "SendReplyToReceive", Request = receive, }, } }; return sequence; }
// Create server side OperationDescription. // Note this method assumes that CacheMetadata has been called on the Receive activity (as part of // the activity tree walk that is done in WorkflowService.GetContractDescriptions) because it relies on // InternalReceiveMessage property of the Receive actitivy to be non-null. public static OperationDescription CreateOperationDescription(Receive receive, ContractDescription contract) { Fx.Assert(receive.InternalReceive != null, "This method can only be called if CacheMetadata has been called on the receive activity"); OperationDescription operation = new OperationDescription(NamingHelper.XmlName(receive.OperationName), contract); if (receive.ProtectionLevel.HasValue) { operation.ProtectionLevel = receive.ProtectionLevel.Value; } // Infer In-Message receive.InternalContent.InferMessageDescription(operation, receive, MessageDirection.Input); // Infer Out-Message if (receive.HasReply) { // At this point, we already know all the following SendReplies are equivalent SendReply sendReply = receive.FollowingReplies[0]; sendReply.InternalContent.InferMessageDescription(operation, sendReply, MessageDirection.Output); } else if (receive.HasFault) { // We infer Receive-SendFault pair as a two-way operation with void return value CheckForDisposableParameters(operation, Constants.EmptyTypeArray); AddOutputMessage(operation, null, Constants.EmptyStringArray, Constants.EmptyTypeArray); } PostProcessOperation(operation); // Behaviors AddSerializerProvider(operation, receive.SerializerOption); AddWorkflowOperationBehaviors(operation, receive.InternalReceive.OperationBookmarkName, receive.CanCreateInstance); if (receive.InternalReceive.AdditionalData.IsInsideTransactedReceiveScope) { operation.IsInsideTransactedReceiveScope = true; EnableTransactionBehavior(operation); if (receive.InternalReceive.AdditionalData.IsFirstReceiveOfTransactedReceiveScopeTree) { operation.IsFirstReceiveOfTransactedReceiveScopeTree = true; } } return operation; }
public static void AddKnownTypesToOperation(Receive receive, OperationDescription operation) { Collection<System.Type> internalKnownTypes = receive.InternalKnownTypes; if (internalKnownTypes != null) { foreach (System.Type type in internalKnownTypes) { if (!operation.KnownTypes.Contains(type)) { operation.KnownTypes.Add(type); } } } }
public static Receive FromOperationDescription(OperationDescription operation) { if (operation == null) { throw FxTrace.Exception.ArgumentNull("operation", "OperationDescription should not be null"); } MessageDescription message; Receive receiveActivity = new Receive(); receiveActivity.ServiceContractName = XName.Get(operation.DeclaringContract.Name, operation.DeclaringContract.Namespace); receiveActivity.OperationName = operation.Name; receiveActivity.DisplayName = operation.Name + "Receive"; receiveActivity.ProtectionLevel = operation.ProtectionLevel; if (operation.Messages != null && operation.Messages.Count > 0) { receiveActivity.Action = operation.Messages[0].Action; } Collection<Type> knownTypes = operation.KnownTypes; if (knownTypes != null) { foreach (Type knownType in knownTypes) { receiveActivity.KnownTypes.Add(knownType); } } // Set SerializerOption if (operation.Behaviors.Contains(typeof(XmlSerializerOperationBehavior))) { receiveActivity.SerializerOption = SerializerOption.XmlSerializer; } else { receiveActivity.SerializerOption = SerializerOption.DataContractSerializer; } bool contentIsParameter = false; bool noReceiveMessageContent = false; message = operation.Messages[0]; // MessageType is null indicating it is not typed message contract if (message.MessageType == null) { if (message.Body.Parts != null) { if (message.Body.Parts.Count != 0) { foreach (MessagePartDescription messagePart in message.Body.Parts) { if (messagePart.Index > 0) { contentIsParameter = true; break; } // Indicating it is a untyped message contract if (!messagePart.Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message))) { contentIsParameter = true; } } } else { noReceiveMessageContent = true; } } else { noReceiveMessageContent = true; } } if (!noReceiveMessageContent) { if (contentIsParameter) { ReceiveParametersContent content = new ReceiveParametersContent(); if (message.Direction == MessageDirection.Input && message.Body.Parts != null) { foreach (MessagePartDescription messagePart in message.Body.Parts) { Argument outArgument = OutArgument.Create(messagePart.Type, ArgumentDirection.Out); content.Parameters.Add(messagePart.Name, (OutArgument)(outArgument)); } } receiveActivity.Content = content; } else { ReceiveMessageContent content = new ReceiveMessageContent(); if (message.Direction == MessageDirection.Input) { if (message.MessageType != null) { content.DeclaredMessageType = message.MessageType; } else { content.DeclaredMessageType = message.Body.Parts[0].Type; } Argument outArgument = OutArgument.Create(content.DeclaredMessageType, ArgumentDirection.Out); content.Message = (OutArgument)outArgument; } receiveActivity.Content = content; } } else { if ((message.Body.ReturnValue != null && message.Body.ReturnValue.Type.IsDefined(typeof(MessageContractAttribute), false)) || (message.Body.ReturnValue != null && message.Body.ReturnValue.Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message)))) { receiveActivity.Content = new ReceiveMessageContent(); } else if (operation.Messages.Count > 1) { if (operation.Messages[1].MessageType != null || operation.Messages[1].Body.ReturnValue.Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message))) { receiveActivity.Content = new ReceiveMessageContent(); } else { receiveActivity.Content = new ReceiveParametersContent(); } } else { receiveActivity.Content = new ReceiveParametersContent(); } } return receiveActivity; }
static Activity GetServiceWorkflow() { Variable<PurchaseOrder> po = new Variable<PurchaseOrder>(); DelegateInArgument<Exception> exception = new DelegateInArgument<Exception> { Name = "UnexpectedException" }; // receive the order request Receive submitPO = new Receive { CanCreateInstance = true, ServiceContractName = Constants.POContractName, OperationName = Constants.SubmitPOName, Content = ReceiveContent.Create(new OutArgument<PurchaseOrder>(po)) }; return new TryCatch { Variables = { po }, Try = new Sequence { Activities = { // receive the order request submitPO, new If { // check if the order is asking for Widgets Condition = new InArgument<bool>( (e) => po.Get(e).PartName.Equals("Widget") ), Then = new If { // check if we have enough widgets in stock Condition = new InArgument<bool>( (e) => po.Get(e).Quantity < 100 ), Then = new SendReply { DisplayName = "Successful response", Request = submitPO, Content = SendContent.Create(new InArgument<string>( (e) => string.Format("Success: {0} Widgets have been ordered!", po.Get(e).Quantity)) ) }, // if we don't have enough widgets, throw an unhandled exception from this operation's body Else = new Throw { Exception = new InArgument<Exception>((e) => new Exception("We don't have that many Widgets.")) } }, // if its not for widgets, reply to the client that we don't carry that part by sending back an expected fault type (POFault) Else = new SendReply { DisplayName = "Expected fault", Request = submitPO, Content = SendContent.Create(new InArgument<FaultException<POFault>>( (e) => new FaultException<POFault>( new POFault { Problem = string.Format("This company does not carry {0}s, but we do carry Widgets.", po.Get(e).PartName), Solution = "Try your local hardware store." }, new FaultReason("This is an expected fault.") ))) } } } }, Catches = { // catch any unhandled exceptions and send back a reply with that exception as a fault message // note: handling this exception in the workflow will prevent the instance from terminating on unhandled exception, // however, if you don't catch the exception and the instance terminates while a reply is still pending, // the WorkflowServiceHost will send the reply automatically with the exception details included new Catch<Exception> { Action = new ActivityAction<Exception> { Argument = exception, Handler = new SendReply { DisplayName = "Unexpected fault", Request = submitPO, Content = SendContent.Create(new InArgument<Exception>(exception)) } } } } }; }
public static void UpdateIsOneWayFlag(Receive receive, OperationDescription operation) { if (!operation.IsOneWay) { receive.SetIsOneWay(false); } }
public static void AddReceiveToFormatterBehavior(Receive receive, OperationDescription operation) { Fx.Assert(receive != null && operation != null, "Argument cannot be null!"); KeyedByTypeCollection<IOperationBehavior> behaviors = operation.Behaviors; WorkflowFormatterBehavior formatterBehavior = behaviors.Find<WorkflowFormatterBehavior>(); if (formatterBehavior == null) { formatterBehavior = new WorkflowFormatterBehavior(); behaviors.Add(formatterBehavior); } formatterBehavior.Receives.Add(receive); }
public static void AddFaultDescription(Receive activity, OperationDescription operation) { if (activity.HasFault) { foreach (SendReply sendFault in activity.FollowingFaults) { string action = null; Type type = null; action = sendFault.Action; SendMessageContent sendReply = sendFault.InternalContent as SendMessageContent; if (sendReply != null) { type = sendReply.InternalDeclaredMessageType; } else { SendParametersContent sendReplyParameters = sendFault.InternalContent as SendParametersContent; if (sendReplyParameters != null) { type = sendReplyParameters.ArgumentTypes[0]; // Exception should be the only parameter in SendFault } } Fx.Assert(type != null, "Exception type cannot be null!"); if (type.IsGenericType && type.GetGenericTypeDefinition() == FaultExceptionType) { Type faultType = type.GetGenericArguments()[0]; bool exists = false; // We expect the number of fault types to be small, so we use iterative comparison foreach (FaultDescription faultDescription in operation.Faults) { if (faultDescription.DetailType == faultType) { if (faultDescription.Action != action) { throw FxTrace.Exception.AsError(new ValidationException(SR.SendRepliesHaveSameFaultTypeDifferentAction)); } else { exists = true; break; } } } if (!exists) { FaultDescription faultDescription = MessageBuilder.CreateFaultDescription(operation, faultType, action); operation.Faults.Add(faultDescription); } } } } }
static WorkflowService GetService() { Variable<Customer> customer = new Variable<Customer>(); Variable<Order> order = new Variable<Order>(); Variable<string> drug = new Variable<string>(); Variable<double> adjustedCost = new Variable<double>(); Variable<int> percentagePaidByInsurance = new Variable<int>(); Variable<CorrelationHandle> customerHandle = new Variable<CorrelationHandle>(); Variable<CorrelationHandle> orderHandle = new Variable<CorrelationHandle>(); XPathMessageContext pathContext = new XPathMessageContext(); pathContext.AddNamespace("psns", Constants.PharmacyServiceNamespace); MessageQuerySet GetOrderQuerySet = new MessageQuerySet { { "OrderID", new XPathMessageQuery("//psns:Order/psns:OrderID",pathContext) } }; MessageQuerySet GetOrderIDQuerySet = new MessageQuerySet { { "OrderID", new XPathMessageQuery("//ser:guid",pathContext) } }; MessageQuerySet customerQuerySet = new MessageQuerySet { { "CustomerID", new XPathMessageQuery("//psns:GetBaseCost/psns:Customer/psns:CustomerID",pathContext) } }; MessageQuerySet customerIDQuerySet = new MessageQuerySet { { "CustomerID", new XPathMessageQuery("//ser:guid",pathContext) } }; // This will use implicit correlation within the workflow using the WorkflowServiceHost's default CorrelationHandle Receive prescriptionRequest = new Receive { DisplayName = "Request Perscription", OperationName = "GetBaseCost", ServiceContractName = Constants.PharmacyServiceContractName, CanCreateInstance = true, //CorrelatesWith = customerHandle, -- add this line for explicit correlation CorrelatesOn = customerQuerySet, Content = new ReceiveParametersContent { Parameters = { {"Customer",new OutArgument<Customer>(customer)}, {"Drug",new OutArgument<string>(drug)}, } } }; // This will use implicit correlation within the workflow using the WorkflowServiceHost's default CorrelationHandle Receive GetInsurancePaymentPercentageRequest = new Receive { DisplayName = "Get Insurance Coverage", ServiceContractName = Constants.PharmacyServiceContractName, OperationName = "GetInsurancePaymentPercentage", CanCreateInstance = true, //CorrelatesWith = customerHandle, -- add this line for explicit correlation CorrelatesOn = customerIDQuerySet, Content = ReceiveContent.Create(new OutArgument<Guid>()) }; // This will explicitly correlate with the SendReply action after the prescriptionRequest using the OrderID (stored in the orderHandle) Receive GetAdjustedCostRequest = new Receive { DisplayName = "Get Adjusted Cost", OperationName = "GetAdjustedCost", ServiceContractName = Constants.PharmacyServiceContractName, CanCreateInstance = true, CorrelatesOn = GetOrderIDQuerySet, CorrelatesWith = orderHandle, Content = ReceiveContent.Create(new OutArgument<Guid>()) }; Activity PrescriptonWorkflow = new Sequence() { Variables = { customer, order, drug, percentagePaidByInsurance, adjustedCost, customerHandle, orderHandle }, Activities = { new WriteLine { Text = "Beginning Workflow" }, new Parallel { Branches = { new Sequence { Activities = { GetInsurancePaymentPercentageRequest, new Assign<int> { To = new OutArgument<int>( (e) => percentagePaidByInsurance.Get(e) ), Value = new InArgument<int>( (e) => new Random().Next(0,100)) }, new SendReply { DisplayName = "Return Percentage", Request = GetInsurancePaymentPercentageRequest, Content = SendContent.Create(new InArgument<int>((e) => percentagePaidByInsurance.Get(e))) } } }, new Sequence { Activities = { prescriptionRequest, new WriteLine { Text = new InArgument<string>(env => (string.Format("{0}, {1}\t{2}", customer.Get(env).LastName ,customer.Get(env).FirstName,customer.Get(env).CustomerID.ToString()))) }, new Assign<Order> { To = new OutArgument<Order>(order), Value = new InArgument<Order>( (e) => new Order() { CustomerID = customer.Get(e).CustomerID, Drug = drug.Get(e), OrderID = Guid.NewGuid() } ) }, new WriteLine { Text = new InArgument<string>(env => (string.Format("OrderID: {0}", order.Get(env).OrderID.ToString()))) }, new Assign<int> { To = new OutArgument<int>( (e) => order.Get(e).Cost ), Value = new InArgument<int>( (e) => new Random().Next(20,50)) }, new SendReply { DisplayName = "Send Adjusted Cost", Request = prescriptionRequest, // Initialize the orderHandle using the MessageQuerySet to correlate with the final GetAdjustedCost request CorrelationInitializers = { new QueryCorrelationInitializer { CorrelationHandle = orderHandle, MessageQuerySet = GetOrderQuerySet } }, Content = SendContent.Create(new InArgument<Order>((e) => order.Get(e))) } } } } }, new Assign<double> { To = new OutArgument<double>( (e) => adjustedCost.Get(e) ), Value = new InArgument<double>( (e) => order.Get(e).Cost * (100-percentagePaidByInsurance.Get(e)) *.01) }, new WriteLine { Text = new InArgument<string>(env => (string.Format("Base Cost: ${0}", order.Get(env).Cost.ToString()))) }, new WriteLine { Text = new InArgument<string>(env => (string.Format("Insurance Coverage: {0}%", percentagePaidByInsurance.Get(env).ToString()))) }, new WriteLine { Text = new InArgument<string>(env => (string.Format("Adjusted Cost: ${0}", decimal.Round(Convert.ToDecimal(adjustedCost.Get(env)),2)))) }, GetAdjustedCostRequest, new SendReply { Request = GetAdjustedCostRequest, Content = SendContent.Create(new InArgument<double>((e) => adjustedCost.Get(e))) }, new WriteLine { Text = "Workflow Completed" } } }; WorkflowService service = new WorkflowService { Name = "PharmacyService", Body = PrescriptonWorkflow, ConfigurationName = "PharmacyService" }; return service; }
//Define the Workflow static Activity ServerWorkflow() { Variable<string> correlationValue = new Variable<string>() { Name = "correlationID" }; MessageQuerySet mqs = new MessageQuerySet() { { "ch", new XPathMessageQuery("//ser:string", new XPathMessageContext()) }, }; Receive requestOne = new Receive { OperationName = "ScenarioOne", ServiceContractName = Constants.ServiceContractName, CanCreateInstance = true, CorrelatesOn = mqs, }; Receive requestTwo = new Receive { OperationName = "ScenarioTwo", ServiceContractName = Constants.ServiceContractName, CanCreateInstance = false, CorrelatesOn = mqs, }; return new Sequence { Variables = { correlationValue }, Activities = { new WriteLine { Text = "Begin Server Workflow. Begin Scenario One." }, new TransactedReceiveScope { // Flow in transaction Request = requestOne, Body = new Sequence { Activities = { new WriteLine { Text = "Begin Scenario One TransactedReceiveScope Body" }, new SendReply { Request = requestOne }, new PrintTxInfo(), // Inner TransactionScope scope joins the existing transaction new TransactionScope { Body = new Sequence { Activities = { new WriteLine { Text = "Begin Scenario One Inner TransactionScope Body" }, new PrintTxInfo(), new WriteLine { Text = "End Scenario One Inner TransactionScope Body" }, }, }, }, new PrintTxInfo(), new WriteLine { Text = "End Scenario One TransactedReceiveScope Body" }, } } }, new WriteLine { Text = "End Scenario One. Begin Scenario Two." }, new TransactedReceiveScope { // Flow in transaction Request = requestTwo, Body = new Sequence { Activities = { new WriteLine { Text = "Begin Scenario Two TransactedReceiveScope Body" }, new SendReply { Request = requestTwo }, new PrintTxInfo(), // Inner TransactionScope joins the existing transaction, but it sets a timeout for the work in its scope. // If the timeout expires the entire transaction will be aborted. new TransactionScope { Timeout = TimeSpan.FromSeconds(2), Body = new Sequence { Activities = { new WriteLine { Text = "Begin Scenario Two Inner TransactionScope Body" }, new Delay { Duration = TimeSpan.FromSeconds(5) }, new PrintTxInfo(), new WriteLine { Text = "End Scenario Two Inner TransactionScope Body" }, }, } }, new PrintTxInfo(), new WriteLine { Text = "End Scenario Two TransactedReceiveScope Body" }, }, }, }, new WriteLine { Text = "End Scenario Two. End Server Workflow\n" }, }, }; }
private void WalkActivityTree() { if (this.knownServiceActivities == null) { if (this.Body == null) { throw System.ServiceModel.Activities.FxTrace.Exception.AsError(new ValidationException(System.ServiceModel.Activities.SR.MissingBodyInWorkflowService)); } WorkflowInspectionServices.CacheMetadata(this.Body); this.knownServiceActivities = new List <Receive>(); this.receiveAndReplyPairs = new HashSet <ReceiveAndReplyTuple>(); Queue <QueueItem> queue = new Queue <QueueItem>(); queue.Enqueue(new QueueItem(this.Body, null, null)); while (queue.Count > 0) { QueueItem item = queue.Dequeue(); Activity activity = item.Activity; TransactedReceiveScope parentTransactedReceiveScope = item.ParentTransactedReceiveScope; TransactedReceiveScope rootTransactedReceiveScope = item.RootTransactedReceiveScope; if (activity is Receive) { Receive receive = (Receive)activity; if (rootTransactedReceiveScope != null) { receive.InternalReceive.AdditionalData.IsInsideTransactedReceiveScope = true; if ((receive == parentTransactedReceiveScope.Request) && (parentTransactedReceiveScope == rootTransactedReceiveScope)) { receive.InternalReceive.AdditionalData.IsFirstReceiveOfTransactedReceiveScopeTree = true; } } this.knownServiceActivities.Add(receive); } else if (activity is SendReply) { SendReply reply = (SendReply)activity; Receive request = reply.Request; if (reply.InternalContent.IsFault) { request.FollowingFaults.Add(reply); } else { if (request.HasReply) { SendReply reply2 = request.FollowingReplies[0]; ContractValidationHelper.ValidateSendReplyWithSendReply(reply2, reply); } request.FollowingReplies.Add(reply); } ReceiveAndReplyTuple tuple = new ReceiveAndReplyTuple(request, reply); this.receiveAndReplyPairs.Add(tuple); } if (activity is TransactedReceiveScope) { parentTransactedReceiveScope = activity as TransactedReceiveScope; if (rootTransactedReceiveScope == null) { rootTransactedReceiveScope = parentTransactedReceiveScope; } } foreach (Activity activity2 in WorkflowInspectionServices.GetActivities(activity)) { QueueItem item2 = new QueueItem(activity2, parentTransactedReceiveScope, rootTransactedReceiveScope); queue.Enqueue(item2); } } } }
public WorkAssignment() { // Define the variables used by this workflow Variable<int> leadID = new Variable<int> { Name = "leadID" }; Variable<string> assignedTo = new Variable<string> { Name = "assignedTo" }; Variable<Assignment> assignment = new Variable<Assignment> { Name = "assignment" }; Receive receive = new Receive { OperationName = "Assign", ServiceContractName = "CreateAssignment", CanCreateInstance = true, Content = new ReceiveParametersContent { Parameters = { { "leadID", new OutArgument<int>(leadID) }, { "assignedTo", new OutArgument<string>(assignedTo) } } } }; // Define the Assignment workflow this.Implementation = () => new Sequence { DisplayName = "WorkAssignment", Variables = { assignment, leadID, assignedTo }, Activities = { receive, new Delay { Duration = TimeSpan.FromSeconds(5) }, new CreateAssignment { LeadID = new InArgument<int>(env => leadID.Get(env)), AssignedTo = new InArgument<string> (env => assignedTo.Get(env)), Assignment = new OutArgument<Assignment> (env => assignment.Get(env)), }, new SendReply { Request = receive }, new Persist { }, new WriteLine { Text = new InArgument<string> (env => "Lead has been assigned to " + assignment.Get(env).AssignedTo), TextWriter = new InArgument<TextWriter> (env => Writer.Get(env)) }, new InvokeMethod { TargetType = typeof(ApplicationInterface), MethodName = "AddAssignment", Parameters = { new InArgument<Assignment>(env => assignment.Get(env)) } }, new WaitForInput<Assignment> { BookmarkName = "GetCompletion", Input = new OutArgument<Assignment> (env => assignment.Get(env)) }, new CompleteAssignment { Assignment = new InOutArgument<Assignment> (env => assignment.Get(env)) }, new InvokeMethod { TargetType = typeof(ApplicationInterface), MethodName = "UpdateAssignment", Parameters = { new InArgument<Assignment>(env => assignment.Get(env)) } }, new WriteLine { Text = new InArgument<string> (env => "Assignment has been completed"), TextWriter = new InArgument<TextWriter> (env => Writer.Get(env)) }, } }; }
static Activity GetServiceWorkflow() { Variable<PurchaseOrder> po = new Variable<PurchaseOrder>(); Variable<OrderStatus> orderStatus = new Variable<OrderStatus>(); Variable<CorrelationHandle> poidHandle = new Variable<CorrelationHandle>(); Variable<bool> complete = new Variable<bool>() { Default = false }; Receive submitPO = new Receive { CanCreateInstance = true, ServiceContractName = Constants.POContractName, OperationName = Constants.SubmitPOName, Content = ReceiveContent.Create(new OutArgument<PurchaseOrder>(po)) // creates a ReceiveMessageContent }; return new Sequence { Variables = { po, orderStatus, poidHandle, complete }, Activities = { submitPO, new WriteLine { Text = "Received Purchase Order" }, new Assign<int> { To = new OutArgument<int>( (e) => po.Get(e).Id ), Value = new InArgument<int>( (e) => new Random().Next() ) }, new SendReply { Request = submitPO, Content = SendContent.Create(new InArgument<int>( (e) => po.Get(e).Id)), // creates a SendMessageContent CorrelationInitializers = { new QueryCorrelationInitializer { // initializes a correlation based on the PurchaseOrder Id sent in the reply message and stores it in the handle CorrelationHandle = poidHandle, MessageQuerySet = new MessageQuerySet { // Here we use our custom LinqMessageQuery for correlatoin // int is the name of the parameter being sent in the outgoing response { "PoId", new LinqMessageQuery(XName.Get("int", Constants.SerializationNamespace))} } } } }, new Assign<OrderStatus> { To = orderStatus, Value = new InArgument<OrderStatus>( (e) => new OrderStatus() { Confirmed = false } ) }, new While // Continue the workflow until the PurchaseOrder is confirmed { Condition = ExpressionServices.Convert<bool>(env => orderStatus.Get(env).Confirmed), Body = new Receive { ServiceContractName = Constants.POContractName, OperationName = Constants.ConfirmPurchaseOrder, CorrelatesWith = poidHandle, // identifies that the ConfirmPurchaseOrder operation is waiting on the PurchaseOrderId that was used to initialize this handle CorrelatesOn = new MessageQuerySet // the query that is used on an incoming message to find the requisite PurchaseOrderId specified in the correlation { // Id is the name of the incoming parameter within the OrderStatus { "PoId", new LinqMessageQuery(XName.Get("Id", Constants.DefaultNamespace))} }, Content = ReceiveContent.Create(new OutArgument<OrderStatus>(orderStatus)) // creates a ReceiveMessageContent } }, new WriteLine { Text = "Purchase Order confirmed." }, new WriteLine { Text = new InArgument<string>( (e) => string.Format("Workflow completed for PurchaseOrder {0}: {1} {2}s", po.Get(e).Id, po.Get(e).Quantity, po.Get(e).PartName) ) }, } }; }
public static void CorrectOutMessageForOperation(Receive receive, OperationDescription operation) { // Remove the original outMessage Fx.Assert(operation.Messages.Count == 2, "OperationDescription must be two-way for CorrectOutMessageForOperation to be invoked!"); operation.Messages.RemoveAt(1); SendReply sendReply = receive.FollowingReplies[0]; sendReply.InternalContent.InferMessageDescription(operation, sendReply, MessageDirection.Output); ContractInferenceHelper.PostProcessOperation(operation); }
public static void UpdateIsOneWayFlag(Receive receive, OperationDescription operation) { // Set InternalReceiveMessage.IsOneWay to false for two-way operations if (!operation.IsOneWay) { receive.SetIsOneWay(false); } }
private static Activity GetApprovePO(Variable<PurchaseOrder> po, Variable<bool> replyPO) { Receive approvePO = new Receive { OperationName = "ApprovePurchaseOrder", CanCreateInstance = true, ServiceContractName = "FinanceService", SerializerOption = SerializerOption.XmlSerializer, Content = ReceiveContent.Create(new OutArgument<PurchaseOrder>(po)) }; Activity workflow = new CorrelationScope() { Body = new Sequence { Variables = { po, replyPO }, Activities = { approvePO, new WriteLine { Text = new InArgument<string>(env =>("Purchase order approval request received")) }, new If { Condition = new InArgument<bool> (env => (po.Get(env).RequestedAmount <= 100)), Then = new Assign<bool> { Value = true, To = new OutArgument<bool>(replyPO) }, Else = new Assign<bool> { Value = false, To = new OutArgument<bool>(replyPO) }, }, new If { Condition = new InArgument<bool> (replyPO), Then = new WriteLine { Text = new InArgument<string>("Purchase Order Approved") }, Else = new WriteLine { Text = new InArgument<string>("Purchase Order Cannot be Approved") }, }, new SendReply { Request = approvePO, Content = SendContent.Create(new InArgument<bool>(replyPO)), }, } } }; return workflow; }
public static void AddKnownTypesToOperation(Receive receive, OperationDescription operation) { Collection<Type> knownTypes = receive.InternalKnownTypes; if (knownTypes != null) { foreach (Type knownType in knownTypes) { // We expect the number of known types to be small, so we use iterative comparison if (!operation.KnownTypes.Contains(knownType)) { operation.KnownTypes.Add(knownType); } } } }
private static Activity GetApprovedVendor(Variable<VendorRequest> vendor, Variable<VendorResponse> replyVendor) { Receive approvedVendor = new Receive { OperationName = "ApprovedVendor", CanCreateInstance = true, ServiceContractName = "FinanceService", Content = ReceiveContent.Create(new OutArgument<VendorRequest>(vendor)) }; Activity workflow = new CorrelationScope() { Body = new Sequence { Variables = { vendor, replyVendor }, Activities = { approvedVendor, new WriteLine { Text = new InArgument<string>(env =>("Query for approved vendor received")) }, new If { Condition = new InArgument<bool> (env => ((vendor.Get(env).requestingDepartment == "Finance"))||Constants.vendors.Contains(vendor.Get(env).Name)), Then = new Assign<VendorResponse> { Value = new InArgument<VendorResponse>( (e) => new VendorResponse{isPreApproved = true} ), To = new OutArgument<VendorResponse>(replyVendor) }, Else = new Assign<VendorResponse> { Value = new InArgument<VendorResponse>( (e) => new VendorResponse{isPreApproved = false} ), To = new OutArgument<VendorResponse>(replyVendor) }, }, new If { Condition = new InArgument<bool> (env => replyVendor.Get(env).isPreApproved), Then = new WriteLine { Text = new InArgument<string>("Vendor is pre-approved") }, Else = new WriteLine { Text = new InArgument<string>("Vendor is not pre-approved") }, }, new SendReply { Request = approvedVendor, Content = SendContent.Create(new InArgument<VendorResponse>(replyVendor)), }, } } }; return workflow; }
public static void RemoveReceiveFromFormatterBehavior(Receive receive, OperationDescription operation) { Fx.Assert(receive != null && operation != null, "Arguments cannot be null!"); KeyedByTypeCollection<IOperationBehavior> behaviors = operation.Behaviors; WorkflowFormatterBehavior formatterBehavior = behaviors.Find<WorkflowFormatterBehavior>(); if (formatterBehavior != null) { formatterBehavior.Receives.Remove(receive); } }
static Activity GetServiceWorkflow() { Variable<PurchaseOrder> po = new Variable<PurchaseOrder>(); Variable<Customer> customer = new Variable<Customer>(); Variable<CorrelationHandle> poidHandle = new Variable<CorrelationHandle>(); Variable<CorrelationHandle> custidHandle = new Variable<CorrelationHandle>(); Variable<bool> complete = new Variable<bool>() { Default = false }; Receive submitPO = new Receive { CanCreateInstance = true, ServiceContractName = Constants.POContractName, OperationName = Constants.SubmitPOName, Content = ReceiveContent.Create(new OutArgument<PurchaseOrder>(po)) // creates a ReceiveMessageContent }; return new Sequence { Variables = { po, customer, poidHandle, custidHandle, complete }, Activities = { submitPO, new WriteLine { Text = "Received PurchaseOrder" }, new Assign<int> { To = new OutArgument<int>( (e) => po.Get(e).Id ), Value = new InArgument<int>( (e) => new Random().Next() ) }, new SendReply { Request = submitPO, Content = SendContent.Create(new InArgument<int>( (e) => po.Get(e).Id)), // creates a SendMessageContent CorrelationInitializers = { new QueryCorrelationInitializer { // initializes a correlation based on the PurchaseOrder Id sent in the reply message and stores it in the handle CorrelationHandle = poidHandle, MessageQuerySet = new MessageQuerySet { // int is the name of the parameter being sent in the outgoing response { "PoId", new XPathMessageQuery("sm:body()/ser:int", Constants.XPathMessageContext) } } } } }, new Parallel { CompletionCondition = complete, Branches = { new While { Condition = true, Body = new Receive { ServiceContractName = Constants.POContractName, OperationName = Constants.UpdatePOName, CorrelatesWith = poidHandle, // identifies that the UpdatePO operation is waiting on the PurchaseOrderId that was used to initialize this handle CorrelatesOn = new MessageQuerySet // the query that is used on an incoming message to find the requisite PurchaseOrderId specified in the correlation { // Id is the name of the incoming parameter within the PurchaseOrder { "PoId", new XPathMessageQuery("sm:body()/defns:PurchaseOrder/defns:Id", Constants.XPathMessageContext) } }, Content = ReceiveContent.Create(new OutArgument<PurchaseOrder>(po)) // creates a ReceiveMessageContent } }, new Sequence { Activities = { new Receive { ServiceContractName = Constants.POContractName, OperationName = Constants.AddCustomerInfoName, Content = ReceiveContent.Create(new OutArgument<PurchaseOrder>(po)), // creates a ReceiveMessageContent CorrelatesWith = poidHandle, // identifies that the AddCustomerInfo operation is waiting on the PurchaseOrderId that was used to initialize this handle CorrelatesOn = new MessageQuerySet // the query that is used on an incoming message to find the requisite PurchaseOrderId specified in the correlation { // Id is the name of the incoming parameter within the PurchaseOrder { "PoId", new XPathMessageQuery("sm:body()/defns:PurchaseOrder/defns:Id", Constants.XPathMessageContext) } }, CorrelationInitializers = { new QueryCorrelationInitializer { // initializes a new correlation based on the CustomerId parameter in the message and stores it in the handle CorrelationHandle = custidHandle, MessageQuerySet = new MessageQuerySet { // CustomerId is the name of the incoming parameter within the PurchaseOrder { "CustId", new XPathMessageQuery("sm:body()/defns:PurchaseOrder/defns:CustomerId", Constants.XPathMessageContext) } } } } }, new WriteLine { Text = "Got CustomerId" }, new Receive { ServiceContractName = Constants.POContractName, OperationName = Constants.UpdateCustomerName, Content = ReceiveContent.Create(new OutArgument<Customer>(customer)), // creates a ReceiveMessageContent CorrelatesWith = custidHandle, // identifies that the UpdateCustomerName operation is waiting on the CustomerId that was used to initialize this handle CorrelatesOn = new MessageQuerySet // the query that is used on an incoming message to find the requisite CustomerId specified in the correlation { // Id is the name of the incoming parameter within the Customer type { "CustId", new XPathMessageQuery("sm:body()/defns:Customer/defns:Id", Constants.XPathMessageContext) } } }, new Assign<bool> { To = new OutArgument<bool>(complete), Value = new InArgument<bool>(true) } } } } }, new WriteLine { Text = new InArgument<string>( (e) => string.Format("Workflow completed for PurchaseOrder {0}: {1} {2}s", po.Get(e).Id, po.Get(e).Quantity, po.Get(e).PartName) ) }, new WriteLine { Text = new InArgument<string>( (e) => string.Format("Order will be shipped to {0} as soon as possible", customer.Get(e).Name) ) } } }; }
private static Activity GetApproveExpense(Variable<Expense> expense, Variable<bool> reply) { Receive approveExpense = new Receive { OperationName = "ApproveExpense", CanCreateInstance = true, ServiceContractName = "FinanceService", SerializerOption = SerializerOption.DataContractSerializer, Content = ReceiveContent.Create(new OutArgument<Expense>(expense)) }; approveExpense.KnownTypes.Add(typeof(Travel)); approveExpense.KnownTypes.Add(typeof(Meal)); Activity workflow = new CorrelationScope() { Body = new Sequence { Variables = { expense, reply }, Activities = { approveExpense, new WriteLine { Text = new InArgument<string>(env =>("Expense approval request received")) }, new If { Condition = new InArgument<bool> (env => (expense.Get(env).Amount <= 100)), Then = new Assign<bool> { Value = true, To = new OutArgument<bool>(reply) }, Else = new Assign<bool> { Value = false, To = new OutArgument<bool>(reply) }, }, new If { Condition = new InArgument<bool> (reply), Then = new WriteLine { Text = new InArgument<string>("Expense Approved") }, Else = new WriteLine { Text = new InArgument<string>("Expense Cannot be Approved") }, }, new SendReply { Request = approveExpense, Content = SendContent.Create(new InArgument<bool>(reply)), }, }, } }; return workflow; }
public static Receive FromOperationDescription(OperationDescription operation) { if (operation == null) { throw FxTrace.Exception.ArgumentNull("operation", "OperationDescription should not be null"); } MessageDescription message; Receive receiveActivity = new Receive(); receiveActivity.ServiceContractName = XName.Get(operation.DeclaringContract.Name, operation.DeclaringContract.Namespace); receiveActivity.OperationName = operation.Name; receiveActivity.DisplayName = operation.Name + "Receive"; receiveActivity.ProtectionLevel = operation.ProtectionLevel; if (operation.Messages != null && operation.Messages.Count > 0) { receiveActivity.Action = operation.Messages[0].Action; } Collection <Type> knownTypes = operation.KnownTypes; if (knownTypes != null) { foreach (Type knownType in knownTypes) { receiveActivity.KnownTypes.Add(knownType); } } // Set SerializerOption if (operation.Behaviors.Contains(typeof(XmlSerializerOperationBehavior))) { receiveActivity.SerializerOption = SerializerOption.XmlSerializer; } else { receiveActivity.SerializerOption = SerializerOption.DataContractSerializer; } bool contentIsParameter = false; bool noReceiveMessageContent = false; message = operation.Messages[0]; // MessageType is null indicating it is not typed message contract if (message.MessageType == null) { if (message.Body.Parts != null) { if (message.Body.Parts.Count != 0) { foreach (MessagePartDescription messagePart in message.Body.Parts) { if (messagePart.Index > 0) { contentIsParameter = true; break; } // Indicating it is a untyped message contract if (!messagePart.Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message))) { contentIsParameter = true; } } } else { noReceiveMessageContent = true; } } else { noReceiveMessageContent = true; } } if (!noReceiveMessageContent) { if (contentIsParameter) { ReceiveParametersContent content = new ReceiveParametersContent(); if (message.Direction == MessageDirection.Input && message.Body.Parts != null) { foreach (MessagePartDescription messagePart in message.Body.Parts) { Argument outArgument = OutArgument.Create(messagePart.Type, ArgumentDirection.Out); content.Parameters.Add(messagePart.Name, (OutArgument)(outArgument)); } } receiveActivity.Content = content; } else { ReceiveMessageContent content = new ReceiveMessageContent(); if (message.Direction == MessageDirection.Input) { if (message.MessageType != null) { content.DeclaredMessageType = message.MessageType; } else { content.DeclaredMessageType = message.Body.Parts[0].Type; } Argument outArgument = OutArgument.Create(content.DeclaredMessageType, ArgumentDirection.Out); content.Message = (OutArgument)outArgument; } receiveActivity.Content = content; } } else { if ((message.Body.ReturnValue != null && message.Body.ReturnValue.Type.IsDefined(typeof(MessageContractAttribute), false)) || (message.Body.ReturnValue != null && message.Body.ReturnValue.Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message)))) { receiveActivity.Content = new ReceiveMessageContent(); } else if (operation.Messages.Count > 1) { if (operation.Messages[1].MessageType != null || operation.Messages[1].Body.ReturnValue.Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message))) { receiveActivity.Content = new ReceiveMessageContent(); } else { receiveActivity.Content = new ReceiveParametersContent(); } } else { receiveActivity.Content = new ReceiveParametersContent(); } } return(receiveActivity); }