Basic understandingI 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 criteriaAs 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 exampleAs 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!