public virtual Sequence CreateActualWorkflow <TResult>() { Expression <Func <ActivityContext, TResult> > lambdaExpression = (Expression <Func <ActivityContext, TResult> >) this.CreateLambdaExpresson <TResult>(); Activity <TResult> we = ExpressionServices.Convert(lambdaExpression); Variable <TResult> result = new Variable <TResult>() { Name = "result" }; Sequence sequence = new Sequence() { Variables = { result }, Activities = { new Assign <TResult>() { Value = new InArgument <TResult>(we), To = result }, new WriteLine() { Text = "result.ToString()" //new VisualBasicValue<string>("result.ToString()") } } }; return(sequence); }
static For Loop() { Variable <int> loopVariable = new Variable <int>(); return(new For() { Variables = { loopVariable }, InitAction = new Assign <int>() { To = loopVariable, Value = 0, }, IterationAction = new Assign <int>() { To = loopVariable, Value = new InArgument <int>(ctx => loopVariable.Get(ctx) + 1) }, // ExpressionServices.Convert is called to convert LINQ expression to a // serializable Expression Activity. Condition = ExpressionServices.Convert <bool>(ctx => loopVariable.Get(ctx) < 10), Body = new WriteLine { Text = new InArgument <string>(ctx => "Value of item is: " + loopVariable.Get(ctx).ToString()), }, }); }
protected void Refresh() { foreach (var item in _expressionServiceMetadata.AllExpressions) { ExpressionServices.Remove(item.Key); } _expressionServiceMetadata.AllExpressions.RemoveAll(p => p.AssemblyName.Equals(this.GetType().Assembly.ManifestModule.Name)); }
public static void ValidateReferenceExpressionXaml <T>(TestExpression te) { Expression <Func <ActivityContext, T> > lambdaExpression = (Expression <Func <ActivityContext, T> >)te.CreateLambdaExpresson <T>(); //Log.TraceInternal("Expression: {0}", lambdaExpression.ToString()); Activity expectedActivity = te.CreateExpectedActivity() as Activity; Activity actualActivity = ExpressionServices.ConvertReference(lambdaExpression); ValidateActivity(expectedActivity, actualActivity); }
public void ReactiveResourceConverter_Roundtrip_UsesExpressionServices() { var observable = new Observable(new Uri("test://uri"), Expression.Default(typeof(object)), null); var expressionServices = new ExpressionServices(); var serializer = new SerializationHelpers(new DataConverter[] { new ReactiveResourceConverter(expressionServices) }); var serialized = serializer.Serialize(observable); var roundtripped = serializer.Deserialize <IAsyncReactiveObservableDefinition>(serialized); Assert.AreNotEqual(observable, roundtripped); Assert.AreEqual(observable.Uri, roundtripped.Uri); Assert.AreEqual(observable.State, roundtripped.State); Assert.IsTrue(new ExpressionEqualityComparer().Equals(Expression.Default(typeof(int)), roundtripped.Expression)); }
public static Activity <Location <TResult> > ConvertReference <TResult>(Expression <Func <ActivityContext, TResult> > expression, Exception expectedException) { Activity <Location <TResult> > result = null; if (expectedException != null) { ExceptionHelpers.CheckForException( expectedException.GetType(), expectedException.Message, () => { result = ExpressionServices.ConvertReference <TResult>(expression); }, true); } else { result = ExpressionServices.ConvertReference <TResult>(expression); } return(result); }
// Workflow variable by Linq public void VariableByLinq() { // Linq treats local variable with special syntax. // See comment in LeafHelper.GetMemberAccessVariableExpression for more info. // The purpose test is to use real compiler generated lambda expression. Variable <string> var = new Variable <string>() { Name = "var", Default = "Linq var test" }; Expression <Func <ActivityContext, string> > expression = (env) => var.Get(env); CoreWf.Statements.Sequence expectedSequence = new CoreWf.Statements.Sequence() { Variables = { var }, Activities = { new WriteLine() { Text = var } } }; CoreWf.Statements.Sequence actualSequence = new CoreWf.Statements.Sequence() { Variables = { var }, Activities = { new WriteLine() { Text = ExpressionServices.Convert(expression) } } }; ExpressionTestRuntime.ValidateActivity(expectedSequence, actualSequence); }
public void HashAlgorithmsMatch(HashAlgorithms enumValue) { string toHash = "`~1234567890-=qwertyuiop[]\\ASDFGHJKL:\"ZXCVBNM<>?ăîșțâ"; HashText hash = new HashText { Algorithm = enumValue, Encoding = new InArgument <Encoding>(ExpressionServices.Convert((env) => System.Text.Encoding.Unicode)) }; Dictionary <string, object> arguments = new Dictionary <string, object>(); arguments.Add(nameof(HashText.Input), toHash); WorkflowInvokerTest invoker = new WorkflowInvokerTest(hash); string activityString = (string)invoker.TestActivity(arguments)[nameof(hash.Result)]; byte[] algorithmBytes = CryptographyHelper.HashData(enumValue, Encoding.Unicode.GetBytes(toHash)); Assert.Equal(activityString, BitConverter.ToString(algorithmBytes).Replace("-", string.Empty)); }
public static Activity <Location <TResult> > TryConvertReference <TResult>(Expression <Func <ActivityContext, TResult> > expression, bool expectSucceeded) { bool isSucceeded; isSucceeded = ExpressionServices.TryConvertReference <TResult>(expression, out Activity <Location <TResult> > resultWorkflow); if (isSucceeded != expectSucceeded) { throw new Exception(string.Format("Expected return is {0}, but actual return is {1}", expectSucceeded, isSucceeded)); } if (false == isSucceeded && resultWorkflow != null) { throw new Exception("TryConvertReference fails, but has a non-null workflow result"); } else if (true == isSucceeded && resultWorkflow == null) { throw new Exception("TryConvertReference succeeded, but has a null workflow result"); } return(resultWorkflow); }
public void SymmetricAlgorithmsEncryptionMatches(SymmetricAlgorithms enumValue) { string toProcess = "`~1234567890-=qwertyuiop[]\\ASDFGHJKL:\"ZXCVBNM<>?ăîșțâ"; string key = "{>@#F09\0"; EncryptText symmetricAlgorithm = new EncryptText { Algorithm = enumValue, Encoding = new InArgument <Encoding>(ExpressionServices.Convert((env) => System.Text.Encoding.Unicode)) }; Dictionary <string, object> arguments = new Dictionary <string, object>(); arguments.Add(nameof(EncryptText.Input), toProcess); arguments.Add(nameof(EncryptText.Key), key); WorkflowInvoker invoker = new WorkflowInvoker(symmetricAlgorithm); string activityString = (string)invoker.Invoke(arguments)[nameof(symmetricAlgorithm.Result)]; byte[] algorithmBytes = CryptographyHelper.DecryptData(enumValue, Convert.FromBase64String(activityString), Encoding.Unicode.GetBytes(key)); Assert.Equal(toProcess, Encoding.Unicode.GetString(algorithmBytes)); }
private static readonly string s_path = string.Empty; //DirectoryAssistance.GetTestBinsDirectory("TempFile.txt"); public static void ValidateExpressionXaml <T>(TestExpression te) { Activity expectedActivity = null, actualActivity = null; Expression <Func <ActivityContext, T> > lambdaExpression = null; lambdaExpression = (Expression <Func <ActivityContext, T> >)te.CreateLambdaExpresson <T>(); //Log.TraceInternal("Expression: {0}", lambdaExpression.ToString()); expectedActivity = te.CreateExpectedActivity() as Activity; if (te.ExpectedConversionException != null) { ExceptionHelpers.CheckForException( te.ExpectedConversionException.GetType(), te.ExpectedConversionException.Message, () => { actualActivity = ExpressionServices.Convert(lambdaExpression); }, true); } else { actualActivity = ExpressionServices.Convert(lambdaExpression); ValidateActivity(expectedActivity, actualActivity); } }
public override Sequence CreateActualWorkflow <TResult>() { Expression <Func <ActivityContext, TResult> > lambdaExpression = Expression.Lambda <Func <ActivityContext, TResult> >(this.CreateLinqExpression(), TestExpression.EnvParameter); Activity <Location <TResult> > we = ExpressionServices.ConvertReference(lambdaExpression); Sequence sequence = new Sequence() { Activities = { new Assign <TResult>() { Value = (TResult)FromValue, To = we }, new WriteLine() { Text = new InArgument <string>(ToExpression) } } }; return(sequence); }
public void KeyedHashAlgorithmsMatchWithSecureString(KeyedHashAlgorithms enumValue) { string toHash = "`~1234567890-=qwertyuiop[]\\ASDFGHJKL:\"ZXCVBNM<>?ăîșțâ"; SecureString keySecureString = TestingHelper.StringToSecureString("{>@#F09\0"); KeyedHashText keyedHash = new KeyedHashText { Algorithm = enumValue, Encoding = new InArgument <Encoding>(ExpressionServices.Convert((env) => System.Text.Encoding.Unicode)) }; Dictionary <string, object> arguments = new Dictionary <string, object>(); arguments.Add(nameof(KeyedHashText.Input), toHash); arguments.Add(nameof(KeyedHashText.KeySecureString), keySecureString); WorkflowInvoker invoker = new WorkflowInvoker(keyedHash); string activityString = (string)invoker.Invoke(arguments)[nameof(keyedHash.Result)]; byte[] algorithmBytes = CryptographyHelper.HashDataWithKey(enumValue, Encoding.Unicode.GetBytes(toHash), Encoding.Unicode.GetBytes(TestingHelper.SecureStringToString(keySecureString))); Assert.Equal(activityString, BitConverter.ToString(algorithmBytes).Replace("-", string.Empty)); }
private Activity CreateXamlSerializableCodeWorkflow() { Variable <Employee> e1 = new Variable <Employee> { Name = "Employee1", Default = ExpressionServices.Convert <Employee>(ctx => new Employee("John", "Doe", 55000.0)) }; Variable <Employee> e2 = new Variable <Employee> { Name = "Employee2", Default = ExpressionServices.Convert <Employee>(ctx => new Employee("Frank", "Kimono", 89000.0)) }; Variable <SalaryStats> stats = new Variable <SalaryStats> { Name = "SalaryStats", Default = ExpressionServices.Convert <SalaryStats>(ctx => new SalaryStats()) }; Variable <Double> v1 = new Variable <double>(); // Lambda expressions do not serialize to XAML. ExpressionServices utility class can be used to // convert them to operator activities, which do serialize to XAML. // ExpressionServices.Convert applies to r-values, which cannot be assigned to. // ExpressionServices.ConvertReference applies to l-values, which can be the target of an assignment. // Note that conversion is supported for a limited set of lambda expressions only. Sequence workflow = new Sequence() { Variables = { e1, e2, stats, v1, }, Activities = { new WriteLine() { Text = ExpressionServices.Convert <string>(ctx => e1.Get(ctx).FirstName + " " + e1.Get(ctx).LastName + " earns " + e1.Get(ctx).Salary.ToString("$0.00")), }, new WriteLine() { Text = ExpressionServices.Convert <string>(ctx => e2.Get(ctx).FirstName + " " + e2.Get(ctx).LastName + " earns " + e2.Get(ctx).Salary.ToString("$0.00")), }, new Assign <double>() { To = ExpressionServices.ConvertReference <double>(ctx => stats.Get(ctx).MinSalary), Value = ExpressionServices.Convert <double>(ctx => Math.Min(e1.Get(ctx).Salary, e2.Get(ctx).Salary)) }, new Assign <double>() { To = ExpressionServices.ConvertReference <double>(ctx => stats.Get(ctx).MaxSalary), Value = ExpressionServices.Convert <double>(ctx => Math.Max(e1.Get(ctx).Salary, e2.Get(ctx).Salary)) }, new Assign <double>() { To = ExpressionServices.ConvertReference <double>(ctx => stats.Get(ctx).AvgSalary), Value = ExpressionServices.Convert <double>(ctx => (e1.Get(ctx).Salary + e2.Get(ctx).Salary) / 2.0) }, new WriteLine() { Text = ExpressionServices.Convert <string>(ctx => String.Format( "Salary statistics: minimum salary is {0:$0.00}, maximum salary is {1:$0.00}, average salary is {2:$0.00}", stats.Get(ctx).MinSalary, stats.Get(ctx).MaxSalary, stats.Get(ctx).AvgSalary)) } }, }; return(workflow); }
private static Activity CreateFlowchartWithFaults(string promoCode, int numKids) { Variable <string> promo = new Variable <string> { Default = promoCode }; Variable <int> numberOfKids = new Variable <int> { Default = numKids }; Variable <double> discount = new Variable <double>(); DelegateInArgument <DivideByZeroException> ex = new DelegateInArgument <DivideByZeroException>(); FlowStep discountNotApplied = new FlowStep { Action = new WriteLine { DisplayName = "WriteLine: Discount not applied", Text = "Discount not applied" }, Next = null }; FlowStep discountApplied = new FlowStep { Action = new WriteLine { DisplayName = "WriteLine: Discount applied", Text = "Discount applied " }, Next = null }; //<Snippet3> FlowDecision flowDecision = new FlowDecision { Condition = ExpressionServices.Convert <bool>((ctx) => discount.Get(ctx) > 0), True = discountApplied, False = discountNotApplied }; //</Snippet3> //<Snippet4> FlowStep singleStep = new FlowStep { Action = new Assign { DisplayName = "discount = 10.0", To = new OutArgument <double> (discount), Value = new InArgument <double> (10.0) }, Next = flowDecision }; //</Snippet4> FlowStep mnkStep = new FlowStep { Action = new Assign { DisplayName = "discount = 15.0", To = new OutArgument <double> (discount), Value = new InArgument <double> (15.0) }, Next = flowDecision }; //<Snippet1> FlowStep mwkStep = new FlowStep { Action = new TryCatch { DisplayName = "Try/Catch for Divide By Zero Exception", Try = new Assign { DisplayName = "discount = 15 + (1 - 1/numberOfKids)*10", To = new OutArgument <double>(discount), Value = new InArgument <double>((ctx) => (15 + (1 - 1 / numberOfKids.Get(ctx)) * 10)) }, Catches = { new Catch <System.DivideByZeroException> { Action = new ActivityAction <System.DivideByZeroException> { Argument = ex, DisplayName = "ActivityAction - DivideByZeroException", Handler = new Sequence { DisplayName = "Divide by Zero Exception Workflow", Activities = { new WriteLine() { DisplayName = "WriteLine: DivideByZeroException", Text = "DivideByZeroException: Promo code is MWK - but number of kids = 0" }, new Assign <double> { DisplayName = "Exception - discount = 0", To = discount, Value = new InArgument <double>(0) } } } } } } }, Next = flowDecision }; //</Snippet1> FlowStep discountDefault = new FlowStep { Action = new Assign <double> { DisplayName = "Default discount assignment: discount = 0", To = discount, Value = new InArgument <double>(0) }, Next = flowDecision }; //<Snippet5> FlowSwitch <string> promoCodeSwitch = new FlowSwitch <string> { Expression = promo, Cases = { { "Single", singleStep }, { "MNK", mnkStep }, { "MWK", mwkStep } }, Default = discountDefault }; //</Snippet5> //<Snippet2> Flowchart flowChart = new Flowchart { DisplayName = "Promotional Discount Calculation", Variables = { discount, promo, numberOfKids }, StartNode = promoCodeSwitch, Nodes = { promoCodeSwitch, singleStep, mnkStep, mwkStep, discountDefault, flowDecision, discountApplied, discountNotApplied } }; //</Snippet2> return(flowChart); }
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)) }, } }); }
// Create a number guessing game workflow program. This workflow // combines several out of the box activities (Sequence, If, // WriteLine, Assign, While, TryCatch, Switch, Expressions) // and two custom activities included in this project (ReadLine and PromptIt). static Activity CreateGuessingGameWF() { // declare working variables Variable <int> attempts = new Variable <int>() { Name = "attempts", Default = 0 }; Variable <int> numberToGuess = new Variable <int>() { Name = "numberToGuess" }; Variable <int> numberFromUser = new Variable <int>() { Name = "numberFromUser" }; Variable <bool> finished = new Variable <bool>() { Name = "finished", Default = false }; DelegateInArgument <FormatException> formatEx = new DelegateInArgument <FormatException>() { Name = "FormatException" }; DelegateInArgument <OverflowException> overFlowEx = new DelegateInArgument <OverflowException>() { Name = "OverflowException" }; return (new Sequence() { DisplayName = "Main Sequence", Variables = { numberToGuess, finished, numberFromUser, attempts }, Activities = { // show a welcome message new WriteLine() { Text = "Starting Game..." }, // calculate a random number and assign it to the numberToGuess variable new Assign <int>() { DisplayName = "Set Random Number to Guess", To = new OutArgument <int>(numberToGuess), Value = new InArgument <int>(env => new Random().Next(1, 100)) }, /// while the user does not guess the number correctly... new While() { DisplayName = "Main Loop", Condition = ExpressionServices.Convert <bool>(env => !finished.Get(env)), // we will ask the user for a number and check if he guessed it (this is what we do inside this sequence) Body = new Sequence() { Activities = { // increase the attempts counter new Assign <int>() { DisplayName = "Increment Attempts", To = new OutArgument <int>(attempts), Value = new InArgument <int>(env => attempts.Get(env) + 1) }, // ask a the user for a number in a TryCatch to handle invalid input new TryCatch() { Try = new Sequence { DisplayName = "Try Catch (getting valid user input)", Activities = { // ask a number to the user new PromptInt() { DisplayName = "Prompt Value to User", Text = "What is your guess?", Result = new OutArgument <int>(numberFromUser) }, //<Snippet1> // check if the number is ok... new Switch <int>() { DisplayName = "Verify Value from User", Expression = ExpressionServices.Convert <int>(env => numberFromUser.Get(env).CompareTo(numberToGuess.Get(env))), Cases = { { 0, new Assign <bool>() { To = new OutArgument <bool>(finished), Value = true } }, { 1, new WriteLine() { Text = " Try a lower number number..." } }, { -1, new WriteLine() { Text = " Try a higher number" } } } } //</Snippet1> } }, // if the user supplied invalid input (e.g. a string instead of a number), we show him an error message Catches = { new Catch <FormatException>() { Action = new ActivityAction <FormatException> { Argument = formatEx, DisplayName = "Wrong Input", Handler = new WriteLine() { Text = " Hey! You must enter a integer number between 1 and 100." } } }, new Catch <OverflowException>() { Action = new ActivityAction <OverflowException> { Argument = overFlowEx, DisplayName = "Wrong Input", Handler = new WriteLine() { Text = " Hey! The number that you entered is too big...You must enter a integer number between 1 and 100." } } } } } } } }, // final message: if the user guessed the number in less than 7 attempts, we show a congratulation message. // if otherwise he found it in 7 or more attempts we encourage him to get more practice new If() { DisplayName = "Display Final Message", Condition = ExpressionServices.Convert <bool>(env => attempts.Get(env) < 7), Then = new WriteLine() { Text = new InArgument <string>(env => string.Format("Congratulations, you've found it in {0} attempts!!!", attempts.Get(env))) }, Else = new WriteLine() { Text = new InArgument <string>(env => string.Format("You've found it in {0} attempts...You need more practice!", attempts.Get(env))) } } } }); }
// create the workflow static Activity CreateProgram() { Variable <TextWriter> writer = new Variable <TextWriter>() { Name = "writer" }; Variable <string> input = new Variable <string> { Name = "input", Default = "" }; return(new Sequence() { Activities = { new NoPersistScope { Body = new TryCatch() { Variables = { writer }, Try = new Sequence() { Activities = { // Output will appear in the out.txt file in the directory where the program runs new CreateTextWriter() { Filename = "out.txt", Result = writer }, // run until the user enters "exit" new While() { Variables = { input }, Condition = ExpressionServices.Convert(ctx => !input.Get(ctx).Equals("exit")), Body = new Sequence() { Activities = { // if the user enters a string, write it in the file new If() { Condition = new InArgument <bool>(ctx => !string.IsNullOrEmpty(input.Get(ctx))), Then = new WriteLine { Text = new InArgument <string>(ctx => string.Format("Echo: {0}", input.Get(ctx))), TextWriter = writer } }, // now, wait for a new string from the user new ReadLine() { BookmarkName = "inputBookmark", Result = input }, } } } } }, Finally = new Dispose() { Target = writer } } } } }); }
public void DifferentArguments() { //Testing Different argument types for DoWhile.Condition // DelegateInArgument // DelegateOutArgument // Variable<T> , Activity<T> and Expression is already implemented. DelegateInArgument <bool> delegateInArgument = new DelegateInArgument <bool>("Condition"); DelegateOutArgument <bool> delegateOutArgument = new DelegateOutArgument <bool>("Output"); TestCustomActivity <InvokeFunc <bool, bool> > invokeFunc = TestCustomActivity <InvokeFunc <bool, bool> > .CreateFromProduct( new InvokeFunc <bool, bool> { Argument = true, Func = new ActivityFunc <bool, bool> { Argument = delegateInArgument, Result = delegateOutArgument, Handler = new Microsoft.CoreWf.Statements.Sequence { DisplayName = "sequence1", Activities = { new Microsoft.CoreWf.Statements.DoWhile { DisplayName = "DoWhile1", Condition = ExpressionServices.Convert <bool>(ctx => delegateInArgument.Get(ctx)), Body = new Microsoft.CoreWf.Statements.Assign <bool> { DisplayName = "Assign1", To = delegateInArgument, Value = new Not <bool, bool> { DisplayName = "Not1", Operand = delegateInArgument } }, }, new Microsoft.CoreWf.Statements.Assign <bool> { DisplayName = "Assign2", To = delegateOutArgument, Value = new Not <bool, bool> { DisplayName = "Not2", Operand = delegateInArgument }, }, new Microsoft.CoreWf.Statements.DoWhile { DisplayName = "DoWhile2", Condition = ExpressionServices.Convert <bool>(ctx => !delegateOutArgument.Get(ctx)), Body = new Microsoft.CoreWf.Statements.Assign <bool> { DisplayName = "Assign3", To = delegateOutArgument, Value = new Not <bool, bool> { DisplayName = "Not3", Operand = delegateInArgument } }, }, }, } } } ); TestSequence sequenceForTracing = new TestSequence { DisplayName = "sequence1", Activities = { new TestDoWhile { DisplayName = "DoWhile1", ActivitySpecificTraces = { new OrderedTraces() { Steps = { new ActivityTrace("Assign1", ActivityInstanceState.Executing), new ActivityTrace("Not1", ActivityInstanceState.Executing), new ActivityTrace("Not1", ActivityInstanceState.Closed), new ActivityTrace("Assign1", ActivityInstanceState.Closed), new ActivityTrace("DelegateArgumentValue<Boolean>", ActivityInstanceState.Executing), new ActivityTrace("DelegateArgumentValue<Boolean>", ActivityInstanceState.Closed), } }, } }, new TestAssign <bool> { DisplayName = "Assign2", ValueActivity = new Test.Common.TestObjects.Activities.Expressions.TestNot <bool, bool>{ DisplayName = "Not2" } }, new TestDoWhile { DisplayName = "DoWhile2", ActivitySpecificTraces = { new OrderedTraces() { Steps = { new ActivityTrace("Assign3", ActivityInstanceState.Executing), new ActivityTrace("Not3", ActivityInstanceState.Executing), new ActivityTrace("Not3", ActivityInstanceState.Closed), new ActivityTrace("Assign3", ActivityInstanceState.Closed), new ActivityTrace("Not<Boolean,Boolean>", ActivityInstanceState.Executing), new ActivityTrace("Not<Boolean,Boolean>", ActivityInstanceState.Closed), } }, } }, } }; invokeFunc.CustomActivityTraces.Add(sequenceForTracing.GetExpectedTrace().Trace); TestIf root = new TestIf(HintThenOrElse.Then) { ConditionActivity = invokeFunc, ThenActivity = new TestWriteLine { Message = "True", HintMessage = "True" }, ElseActivity = new TestWriteLine { Message = "False", HintMessage = "This is not expected" }, }; TestRuntime.RunAndValidateWorkflow(root); }
// Create a workflow that shows different ways of using InvokeMethod. // All instances of the InvokeMethod activity in this workflow // are invoking methods from TestClass class (file TestClass.cs) static Activity CreateWf() { TestClass testClass = new TestClass(); Variable <string> outParam = new Variable <string>() { Default = "this is an out param" }; Variable <int> resultValue = new Variable <int>(); Variable <TestClass> varTestClass = new Variable <TestClass>(ctx => new TestClass()); return(new Sequence { Variables = { outParam, resultValue, varTestClass }, Activities = { // use InvokeMethod to call an instance method without parameters new WriteLine { Text = "Instance Method Call" }, new InvokeMethod { TargetObject = new InArgument <TestClass>(ctx => testClass), MethodName = "InstanceMethod" }, // use InvokeMethod to call an instance method with two parameters (string and int) new WriteLine(), new WriteLine { Text = "Instance Method Call with Parameters" }, new InvokeMethod { TargetObject = new InArgument <TestClass>(ctx => testClass), MethodName = "InstanceMethod", Parameters = { new InArgument <string>("My favorite number is"), new InArgument <int>(42) } }, // use InvokeMethod to call an instance method with two parameters (string and int) // and a parameter array of type string[]. new WriteLine(), new WriteLine { Text = "Instance Method Call with Parameter Arrays" }, //<Snippet1> new InvokeMethod { TargetObject = new InArgument <TestClass>(ctx => testClass), MethodName = "InstanceMethod", Parameters = { new InArgument <string>("My favorite number is"), new InArgument <int>(42), new InArgument <string>("first item of the param array"), new InArgument <string>("second item of the param array"), new InArgument <string>("third item of the param array") } }, //</Snippet1> // use InvokeMethod to call an instance method with two parameters (two int numbers) // and a result of type int. In this case, the result value is bound to a variable // and used in another activity (is displayed in the console using WriteLine) new WriteLine { }, new WriteLine { Text = "Instance Method Call with Parameters and Return Value" }, //<Snippet2> new InvokeMethod <int> { TargetObject = new InArgument <TestClass>(ctx => testClass), MethodName = "InstanceMethodWithResult", Parameters = { new InArgument <int>(20), new InArgument <int>(22) }, Result = resultValue }, //</Snippet2> new WriteLine { Text = new InArgument <string>(ctx => string.Format("....Result: {0}", resultValue.Get(ctx))) }, // use InvokeMethod to call a static method with two parameters (string and int). All options // for calling instance methods are also available for static methods. new WriteLine(), new WriteLine { Text = "Static Method Call with Parameters" }, new InvokeMethod { TargetType = typeof(TestClass), MethodName = "StaticMethod", Parameters = { new InArgument <string>("My favorite number is"), new InArgument <int>(42) } }, // use InvokeMethod to call an instance method with one generic parameter (int this case, <string>) new WriteLine(), new WriteLine { Text = "Generic Instance Method Call with Generic Parameters" }, //<Snippet5> new InvokeMethod { TargetObject = new InArgument <TestClass>(ctx => testClass), MethodName = "GenericInstanceMethod", GenericTypeArguments ={ typeof(string) }, Parameters = { new InArgument <string>("Hello world") } }, //</Snippet5> // use InvokeMethod to call a static method with two generic parameters (int this case, <string> and <int>) new WriteLine(), new WriteLine { Text = "Generic Static Method Call with Two Generic Parameters" }, new InvokeMethod { TargetType = typeof(TestClass), MethodName = "GenericStaticMethod", GenericTypeArguments = { typeof(string), typeof(int) }, Parameters = { new InArgument <string>("Favorite Number"), new InArgument <int>(42) } }, // use InvokeMethod to call an instance method that has one parameter // passed by reference (a string param). In this case, the reference parameter is bound // to a variable (outParam) and used in another activity (is displayed in the console using WriteLine) new WriteLine(), new WriteLine { Text = "Instance Method Call with Parameters by Reference" }, new InvokeMethod { TargetObject = new InArgument <TestClass>(ctx => testClass), MethodName = "InstanceMethod", Parameters = { new InArgument <string>("My favorite number is"), new InArgument <int>(42), new InOutArgument <string>(outParam) } }, new WriteLine { Text = ExpressionServices.Convert <string>(ctx => string.Format("....out param changed to: {0}", outParam.Get(ctx))) }, // use InvokeMethod to call an asynchronous instance method new WriteLine(), new WriteLine { Text = "Async Instance Method Call" }, //<Snippet3> new InvokeMethod { TargetObject = new InArgument <TestClass>(ctx => testClass), MethodName = "AsyncMethodSample", RunAsynchronously = true, Parameters = { new InArgument <string>("Hello async"), } }, //</Snippet3> // use InvokeMethod to call an instance method in varTestClass // store a value into the TestClass Variable new WriteLine(), new WriteLine { Text = "Store a Value" }, new InvokeMethod { TargetObject = new InArgument <TestClass>(varTestClass), MethodName = "StoreValue", Parameters = { new InArgument <int>(42), } }, // use InvokeMethod to call another instance method in varTestClass // retrieve it back new WriteLine(), new WriteLine { Text = "Get a Value" }, new InvokeMethod <int> { TargetObject = new InArgument <TestClass>(varTestClass), MethodName = "GetValue", Result = resultValue, }, // a different way of printing it out //<Snippet4> new InvokeMethod { TargetType = typeof(Console), MethodName = "WriteLine", Parameters = { new InArgument <string>(ctx => String.Format("....the stored value is {0}", resultValue.Get(ctx))), } }, //</Snippet4> } }); }
private Activity GetImplementation() { Variable <double> discount = new Variable <double>(); Variable <string> discountCode = new Variable <string>(); Variable <bool> isStudent = new Variable <bool>() { Default = _isStudent }; Variable <bool> isMarried = new Variable <bool> { Default = _isMarried }; Variable <bool> haveChild = new Variable <bool> { Default = _haveChild }; FlowStep returnDiscountCode = new FlowStep { Action = new Assign <string> { DisplayName = "Return Discount Code", To = new OutArgument <string>((ctx) => DiscountCode.Get(ctx)), Value = new InArgument <string>(discountCode) }, Next = null }; FlowStep printDiscount = new FlowStep { Action = new WriteLine { DisplayName = "WriteLine: Discount Applied", Text = discountCode }, Next = returnDiscountCode }; FlowStep applyDefaultDiscount = new FlowStep { Action = new Assign <double> { DisplayName = "Default Discount is 0%", To = discount, Value = new InArgument <double>(0) }, Next = printDiscount }; FlowStep applyBaseDiscount = new FlowStep { Action = new Assign <double> { DisplayName = "Base Discount is 5%", To = discount, Value = new InArgument <double>(5) }, Next = printDiscount }; FlowStep applyStandardDiscount = new FlowStep { Action = new Assign <double> { DisplayName = "Standard Discount is 10%", To = discount, Value = new InArgument <double>(10) }, Next = printDiscount }; FlowStep applyPremiumDiscount = new FlowStep { Action = new Assign <double> { DisplayName = "Standard Discount is 15%", To = discount, Value = new InArgument <double>(15) }, Next = printDiscount }; FlowSwitch <string> discountCodeSwitch = new FlowSwitch <string> { Expression = discountCode, Cases = { { "STD", applyBaseDiscount }, { "MNC", applyStandardDiscount }, { "MWC", applyPremiumDiscount }, }, Default = applyDefaultDiscount }; FlowStep noDiscount = new FlowStep { Action = new Assign <string> { DisplayName = "No Discount", To = discountCode, Value = new InArgument <string>("NONE") }, Next = discountCodeSwitch }; FlowStep studentDiscount = new FlowStep { Action = new Assign <string> { DisplayName = "Student Discount is appplied", To = discountCode, Value = new InArgument <string>("STD") }, Next = discountCodeSwitch }; FlowStep marriedWithNoChildDiscount = new FlowStep { Action = new Assign <string> { DisplayName = "Married with no child Discount is applied", To = discountCode, Value = new InArgument <string>("MNC") }, Next = discountCodeSwitch }; FlowStep marriedWithChildDiscount = new FlowStep { Action = new Assign <string> { DisplayName = "Married with child Discount is 15%", To = discountCode, Value = new InArgument <string>("MWC") }, Next = discountCodeSwitch }; FlowDecision singleFlowDecision = new FlowDecision { Condition = ExpressionServices.Convert <bool>((ctx) => isStudent.Get(ctx)), True = studentDiscount, False = noDiscount, }; FlowDecision marriedFlowDecision = new FlowDecision { Condition = ExpressionServices.Convert <bool>((ctx) => haveChild.Get(ctx)), True = marriedWithChildDiscount, False = marriedWithNoChildDiscount, }; FlowDecision startNode = new FlowDecision { Condition = ExpressionServices.Convert <bool>((ctx) => isMarried.Get(ctx)), True = marriedFlowDecision, False = singleFlowDecision }; return(new Flowchart() { DisplayName = "Auto insurance discount calculation", Variables = { discount, isMarried, isStudent, haveChild, discountCode }, StartNode = startNode, Nodes = { startNode, marriedFlowDecision, singleFlowDecision, marriedWithChildDiscount, marriedWithNoChildDiscount, studentDiscount, noDiscount, discountCodeSwitch, applyBaseDiscount, applyDefaultDiscount, applyPremiumDiscount, applyStandardDiscount, printDiscount, returnDiscountCode } }); }
static Activity CreateWorkflow() { Variable <int> numberOfBells = new Variable <int>() { Name = "numberOfBells", Default = DateTime.Now.Hour }; var counter = new Variable <int>() { Name = "counter", Default = 1, }; return(new Sequence() { DisplayName = "Main Sequence", Variables = { numberOfBells, counter }, Activities = { new WriteLine { DisplayName = "Hello", Text = "Hello, World!", }, new If { DisplayName = "Adjust For PM", Condition = ExpressionServices.Convert <bool>(env => numberOfBells.Get(env) > 12), Then = new Assign <int> { DisplayName = "Adjust Bells", // level 3 } }, new While { DisplayName = "Sound Bell(s)", Condition = ExpressionServices.Convert <bool>(env => counter.Get(env) <= numberOfBells.Get(env)), Body = new Sequence { DisplayName = "Sound Bell", // level 3 }, }, new WriteLine { DisplayName = "Display Time", Text = "The time is " + DateTime.Now.ToString(), }, new If { DisplayName = "Greeting", Condition = ExpressionServices.Convert <bool>(env => DateTime.Now.Hour >= 18), Then = new WriteLine{ Text = "Good Evening" }, Else = new WriteLine{ Text = "Good Day" }, } } }); }
static Activity CreateWorkflow() { Variable <int> numberBells = new Variable <int>() { Name = "numberBells", Default = DateTime.Now.Hour }; Variable <int> counter = new Variable <int>() { Name = "counter", Default = 1 }; return(new Sequence() { DisplayName = "Main Sequence", Variables = { numberBells, counter }, Activities = { new WriteLine() { DisplayName = "Hello", Text = "Hello, World!" }, new If() { DisplayName = "Adjust for PM", // Code to be added here in Level 2 Condition = ExpressionServices.Convert <bool>(env => numberBells.Get(env) > 12), Then = new Assign <int>() { DisplayName = "Adjust Bells", // Code to be added here in Level 3 To = new OutArgument <int>(numberBells), Value = new InArgument <int>(env => numberBells.Get(env) - 12) } }, new While() { DisplayName = "Sound Bells", // Code to be added here in Level 2 Condition = ExpressionServices.Convert <bool> (env => counter.Get(env) <= numberBells.Get(env)), Body = new Sequence() { DisplayName = "Sound Bell", // Code to be added here in Level 3 Activities = { new WriteLine() { Text = new InArgument <string>(env => counter.Get(env).ToString()) }, new Assign <int>() { DisplayName = "Increment Counter", To = new OutArgument <int>(counter), Value = new InArgument <int>(env => counter.Get(env) + 1) }, new Delay() { Duration = TimeSpan.FromSeconds(1) } } } }, new WriteLine() { DisplayName = "Display Time", Text = "The time is: " + DateTime.Now.ToString() }, new If() { DisplayName = "Greeting", // Code to be added here in Level 2 Condition = ExpressionServices.Convert <bool>(env => DateTime.Now.Hour >= 18), Then = new WriteLine() { Text = "Good Evening" }, Else = new WriteLine() { Text = "Good Day" } } } }); }
private static Activity GetPropertyWorkflow() { // Correlation handle used to link operations together Variable <CorrelationHandle> operationHandle = new Variable <CorrelationHandle>(); // The generated property Id Variable <Guid> propertyId = new Variable <Guid>(); // Variable used to indicate that the workflow should finish Variable <bool> finished = new Variable <bool>("Finished", false); Variable <string> address = new Variable <string>(); Variable <string> owner = new Variable <string>(); Variable <double> askingPrice = new Variable <double>(); // Initial receive - this kicks off the workflow Receive receive = new Receive { CanCreateInstance = true, OperationName = "UploadPropertyInformation", ServiceContractName = XName.Get("IProperty", ns), Content = new ReceiveParametersContent { Parameters = { { "address", new OutArgument <string>(address) }, { "owner", new OutArgument <string>(owner) }, { "askingPrice", new OutArgument <double>(askingPrice) } } } }; // Define the local namespace XPathMessageContext messageContext = new XPathMessageContext(); messageContext.AddNamespace("local", ns); // Extracts the guid sent back to the client on the initial response MessageQuerySet extractGuid = new MessageQuerySet { { "PropertyId", new XPathMessageQuery("sm:body()/ser:guid", messageContext) } }; // Extracts the guid sent up with the property image MessageQuerySet extractGuidFromUploadRoomInformation = new MessageQuerySet { { "PropertyId", new XPathMessageQuery(@"sm:body()/local:UploadRoomInformation/local:propertyId", messageContext) } }; // Receive used to indicate that the upload is complete Receive receiveDetailsComplete = new Receive { OperationName = "DetailsComplete", ServiceContractName = XName.Get("IProperty", ns), CorrelatesWith = operationHandle, CorrelatesOn = extractGuid, Content = ReceiveContent.Create(new OutArgument <Guid>(propertyId)) }; Variable <string> roomName = new Variable <string>(); Variable <double> width = new Variable <double>(); Variable <double> depth = new Variable <double>(); // Receive room information Receive receiveRoomInfo = new Receive { OperationName = "UploadRoomInformation", ServiceContractName = XName.Get("IProperty", ns), CorrelatesWith = operationHandle, CorrelatesOn = extractGuidFromUploadRoomInformation, Content = new ReceiveParametersContent { Parameters = { { "propertyId", new OutArgument <Guid>() }, { "roomName", new OutArgument <string>(roomName) }, { "width", new OutArgument <double>(width) }, { "depth", new OutArgument <double>(depth) }, } } }; return(new Sequence { Variables = { propertyId, operationHandle, finished, address, owner, askingPrice }, Activities = { receive, new WriteLine { Text = "Assigning a unique ID" }, new Assign <Guid> { To = new OutArgument <Guid> (propertyId), Value = new InArgument <Guid> (Guid.NewGuid()) }, new WriteLine { Text = new InArgument <string> (env => string.Format("{0} is selling {1} for {2}.\r\nAssigned unique id {3}.",owner.Get(env), address.Get(env), askingPrice.Get(env), propertyId.Get(env))) }, new SendReply { Request = receive, Content = SendContent.Create(new InArgument <Guid> (env => propertyId.Get(env))), CorrelationInitializers = { new QueryCorrelationInitializer { CorrelationHandle = operationHandle, MessageQuerySet = extractGuid } } }, new While { Condition = ExpressionServices.Convert <bool>(env => !finished.Get(env)), Body = new Pick { Branches = { new PickBranch { Variables = { roomName, width,depth }, Trigger = receiveRoomInfo, Action = new WriteLine{ Text = new InArgument <string> (env => string.Format("Room '{0}' uploaded, dimensions {1}W x {2}D",roomName.Get(env), width.Get(env), depth.Get(env))) }, }, new PickBranch { Trigger = receiveDetailsComplete, Action = new Sequence { Activities = { new Assign <bool> { To = new OutArgument <bool>(finished), Value = new InArgument <bool>(true) }, new WriteLine { Text = "Property Details Complete" } } } } } } }, new WriteLine { Text = "Finished!" } } }); }
public EncryptFile() { Algorithm = SymmetricAlgorithms.AESGCM; KeyEncoding = new InArgument <Encoding>(ExpressionServices.Convert((env) => System.Text.Encoding.UTF8)); }