📜 ⬆️ ⬇️

Windows Workflow Foundation - for what and in what cases to apply


Basic understanding

I remember that even at the university, before the implementation of any algorithm, we described it as a block diagram, and only after that we proceeded directly to coding. Workflow , as one of the programming paradigms, along with procedural and object-oriented approaches, allows us to visually implement any process using a set of predefined function blocks ( Activity ), while eliminating its subsequent coding.

The WF library, being one of the implementations of the Workflow paradigm, provides the following main features:
')
- a rich set of functional blocks;
- extension of the set of standard functional blocks by user;
- saving and resuming Workflow instances in the process of their execution;
- Use Workflow designer in your application;
- integration with WCF ;
- step-by-step diagnostics directly in the Workflow designer;
- and much more.

Application criteria

As is known, each technology has its own scope. To determine the need to use WF when implementing a specific algorithm / process, I apply 3 criteria:

1. The implementation of the algorithm / process is constantly changing.

In our company, we have developed a Workflow subsystem, which is the core of all products. Having, for example, dozens of customers of our products, who have dozens of processes, we get hundreds of different changing processes.

2. The process / algorithm has a long execution time.

In our products, the life cycle of processes is calculated in days and weeks. At the same time, in the event of a server failure or overload, the processes should correctly resume and continue execution.

3. It is necessary to provide the ability to change the algorithm / process to the end user without the intervention of the programmer.

We have developed our own designer in order to simplify and facilitate the editing of processes to the end user (business intelligence) as much as possible. This allows you to take the burden off developers. And the ability to see and easily change their own processes is very attractive to customers.

Thus, if at least one of the above requirements is relevant, WF should be considered as a possible implementation variant of the algorithm / process.

Introductory example

As an introductory example of using WF, I am implementing a Workflow process that will answer the question about the appropriateness of using WF .
1. Create a new IsWWFUsefullSample project using the Blank Solution template:



2. Add a new project IsWWFUsefullSample.Activities using the Activity Designer Library template:



3. Delete the existing ActivityDesigner1.xaml file and add a new item using the Activity template:



4. I open the Activity in the designer and add the necessary parameters of type Boolean:

- three incoming parameters that meet our criteria: IsLongRunning, IsChangeable, IsDesignerNecessary;

- one outgoing parameter to return the result: Result.

It is worth mentioning that at the moment only VB.Net syntax can be used to describe expressions and types within the Workflow Activity . They promise to add support for C # .



5. To analyze incoming parameters I use three nested If Activities ( Toolbox -> Control Flow -> If ), although of course you can do with one. To assign the result I use Assign Activity ( Toolbox -> Primitives -> Assign ). The result is the following algorithm:



6. Workflow process is ready. To use it, I add a new IsWWFUsefullSample.TestClient application based on the Workflow Console Application template:




7. Delete the file Workflow1.xaml.

8. Add a link to the IsWWFUsefullSample.Activities project.



9. Implement the Main method. He prompts the user to answer three questions, starts the Workflow process with the initial data obtained and displays the result of the calculation.

// ==============================================================
// <copyright file="Program.cs" company="The World as a Workflow">
// Copyright (c) The World as a Workflow. All rights reserved.
// </copyright>
// <author>Alexander Nechyporenko</author>
// <date>2011-07-12</date>
// ==============================================================

namespace IsWWFUsefullSample.TestClient
{
using System;
using System.Activities;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using IsWWFUsefullSample.Activities;

/// <summary>
/// Console program class.
/// </summary>
public class Program
{
/// <summary>
/// Program starting point.
/// </summary>
/// <param name="args">Program parameters.</param>
public static void Main(string[] args)
{
// Question answers
const string Yes = "yes";
const string No = "no";
var answers = new List<string> { Yes, No };

// Create new activity instance
var activity = new IsWWFUsefull();
var parameters = new Dictionary<string, object>();

do
{
Console.WriteLine("Please, answer following questions to determine necessity of using WWF.");
Console.WriteLine();

// Read activity input parameters
parameters["IsLongRunning"] = ReadAnswer("Is process/algorithm long running?", answers) == Yes;
parameters["IsChangeable"] = ReadAnswer("Is process/algorithm frequently changed?", answers) == Yes;
parameters["IsDesignerNecessary"] =
ReadAnswer("Do you need a visual designer for your process/algorithm?", answers) == Yes;

// Execute activity
var result = WorkflowInvoker.Invoke(activity, parameters);

// Show result
Console.WriteLine();
if ((bool)result["Result"])
{
Console.WriteLine("Use WWF!");
}
else
{
Console.WriteLine("You don't need WWF but still can use it if you like it :).");
}
Console.WriteLine("---------------------------------------------------------------------");
Console.WriteLine();
}
while (ReadAnswer("Do you want to proceed?", answers) == Yes);

return;
}

/// <summary>
/// Read answer from console.
/// </summary>
/// <param name="question">Question text.</param>
/// <param name="answers">A list of posible</param>
/// <returns>Answer text.</returns>
private static string ReadAnswer(string question, IList<string> answers)
{
// Prepare answers prompting string
var answersString = new StringBuilder();
for (var i = 0; i < answers.Count; i++)
{
answersString.AppendFormat(i == 0 ? "{0}" : "/{0}", answers[i]);
}

// Read and validate the answer
var text = string.Empty;
var answer = string.Empty;
do
{
if (!string.IsNullOrEmpty(text))
{
Console.WriteLine(
string.Format("'{0}' doesn't belong to list of posible answers: '{1}'.", text, answersString));
}

Console.Write(string.Format("{0} ({1}): ", question, answersString));

text = Console.ReadLine();
answer = answers.Where(a => a == text.ToLower()).FirstOrDefault();
}
while (answer == null);

return answer;
}
}
}


10. I launch and test the application:



Project sources can be downloaded here .

All successful architectural solutions and pleasant coding!

Source: https://habr.com/ru/post/125008/


All Articles