Mohammed Atef’s Technical blog

Workflow Foundation 4.0 Collections

Introduction

In this post we will see an important built in activities comes with Workflow foundation 4.0., these built-in activities enable you to manipulate a collection in your workflow. this post guide you to do the most required actions for manipulating collections like add,remove and delete items from collection and sorting, searching and clearing the collection.

We will build a console application that demonstrates these activities using a Book Store application.

Building Book Store application
To build the Book Store application you should follow the below steps

1- Create new console application and add System.Activities reference to the new project

2- Open the program.cs file and add the following list of code for declaring BookStoreListItem this class contains a few public properties that store information about an item to be stored.

   1: public class BookStoreListItem
   2:     {
   3:         public string Description { get; set; }
   4:         public int Quantity { get; set; }
   5:         public decimal UnitPrice { get; set; }
   6:         public string Author { get; set; }
   7:         public string BookName { get; set; }
   8:         public BookStoreListItem(string description, int quantity, decimal unitPrice,string author, string bookName)
   9:         {
  10:             Description = description;
  11:             Quantity = quantity;
  12:             UnitPrice = unitPrice;
  13:             BookName = bookName;
  14:             Author = author;
  15:         }
  16:         public BookStoreListItem(string bookName)
  17:         {
  18:             BookName= bookName;
  19:         }
  20:     }

3- Initiate the Workflow by adding the following namespace to the top of program.cs class

using System.Activities.Expressions; now add the following list of code after the closed practices for the main method in the program.cs class

   1: private static Activity CollectionWF()
   2:         {
   3:             // myList is a collection of ListItem objects
   4:             Variable<ICollection<BookStoreListItem>> myList = new Variable<ICollection<BookStoreListItem>>()
   5:             {
   6:                 Name = "MyList",
   7:                 Default = new LambdaValue<ICollection<BookStoreListItem>>
   8:                     (env => new List<BookStoreListItem>())
   9:             };
  10:             return new Sequence
  11:             {
  12:                 Variables = { myList },
  13:                 Activities =
  14:                 {
  15:                     new WriteLine
  16:                     {
  17:                         Text = "Workflow starting..."
  18:                     },
  19:                     new AddToCollection<BookStoreListItem>
  20:                     {
  21:                         Collection = myList,
  22:                         Item = new LambdaValue<BookStoreListItem>
  23:                         (env => new BookStoreListItem("New WorkFlow 4.0 book", 5, 50,"Mohammed", "WorkFlow 4.0"))
  24:                     },
  25:                     new AddToCollection<BookStoreListItem>
  26:                     {
  27:                         Collection = myList,
  28:                         Item = new LambdaValue<BookStoreListItem>
  29:                         (env => new BookStoreListItem("New Linq 4.0 book", 3, 30,"Sherif", "LINQ 4.0"))
  30:                     },
  31:                     new AddToCollection<BookStoreListItem>
  32:                     {
  33:                         Collection = myList,
  34:                         Item = new LambdaValue<BookStoreListItem>
  35:                         (env => new BookStoreListItem("New Windows Communication Foundation 4.0 book", 8, 80,"Atef", "WCF 4.0"))
  36:                     },
  37:                     new AddToCollection<BookStoreListItem>
  38:                     {
  39:                         Collection = myList,
  40:                         Item = new LambdaValue<BookStoreListItem>
  41:                         (env => new BookStoreListItem("Visual studio 2010 book", 15, 40,"Khalid", "VS 2010"))
  42:                     },
  43:                     new WriteLine
  44:                     {
  45:                         Text = "Workflow ended"
  46:                     }
  47:                 }
  48:             };
  49:         }

This workflow defines a variable that is a collection of BookStoreListItem classes named myList. The variable can be any typeof collection that supports the ICollection interface.the LambdaValue Represents a lambda expression used as an r-value, which supports binding of In arguments so it is bind the default value of myList with the returned new instance of BookStoreListItem class .

After that we are going to build the sequence activity for our workflow and the sequence activity will have the following activities

a- writeline activity that printing “Workflow starting…”

b- four AddToCollection activity that used for adding new item of BookStoreListItem to myList

c- another writeline activity to print “Workflow ended…”

4- Now we need to invoke the workflow, so please add the following lines of code in the main method at program.cs class

   1: WorkflowInvoker.Invoke(CollectionWF());
   2: Console.WriteLine("Press ENTER to exit");
   3: Console.ReadLine();

These few line of code used to invoke the workflow by calling collectionWF into the Invoke method.

If you have run the application now you will find the following lines printed

Workflow starting…

Workflow ended…

Press ENTER to exit

5- Printing Collection , we will provide a way to display the contents of the books list, to do that right-click the project and choose Add new Item and select Class, For the class name, enter PrintBooksList.cs. The implementation of this class is shown in Listing below

   1: using System;
   2: using System.Activities;
   3: using System.Collections.Generic;
   4: namespace WFFBookStoreApp
   5: {
   6:     public sealed class PrintBooksList: CodeActivity
   7:     {
   8:         public InArgument<ICollection<BookStoreListItem>> Collection { get; set; }
   9:
  10:         protected override void Execute(CodeActivityContext context)
  11:         {
  12:             ICollection<BookStoreListItem> list =
  13:             this.Collection.Get<ICollection<BookStoreListItem>>(context);
  14:             if (list.Count == 0)
  15:             {
  16:                 Console.WriteLine("The Book list is empty");
  17:             }
  18:             else
  19:             {
  20:                 foreach (BookStoreListItem l in list)
  21:                 {
  22:                     Console.WriteLine("Book Named {0} has the following information :", l.BookName);
  23:                     Console.WriteLine("(Description:{0} ,Quantity: {1},Price: {2} ,Author {3})",
  24:                     l.Description,l.Quantity.ToString(), l.UnitPrice, l.Author);
  25:                 }
  26:                 Console.WriteLine();
  27:             }
  28:         }
  29:     }
  30: }

This custom activity receives the collection as an input argument. It expects a collection of BookStoreListItem classes. the overridden execute method first check if the list empty or not, if yes it is printing the book list is empty message, else it is loop throw the list and print each book item information, this code is very simple you can understand but if you do not know how to create custom activity please visit the following link WFF 4.0 custom activity.

6- To use this custom activity, Open the program.cs file and add the following activity definition to the collectionWF () method before the final writeline activity

   1: new PrintBooksList
   2:                     {
   3:                         Collection=myList
   4:                     },

If you run the application now you will find the following message printed

clip_image002

7- Sorting the collection, we will provide a way to sort the books list by book price, to do that right-click the project and choose Add new Item and select Class, For the class name, enter SortBooksList.cs. The implementation of this class is shown in Listing below

   1: using System;
   2: using System.Activities;
   3: using System.Collections.Generic;
   4: namespace WFFBookStoreApp
   5: {
   6:     public sealed class SortBooksList : CodeActivity
   7:     {
   8:         public InOutArgument<ICollection<BookStoreListItem>> Collection { get; set; }
   9:         protected override void Execute(CodeActivityContext context)
  10:         {
  11:             ICollection<BookStoreListItem> tempList = this.Collection.Get<ICollection<BookStoreListItem>>(context);
  12:             if (tempList.Count > 0)
  13:             {
  14:                 List<BookStoreListItem> sortedList = new List<BookStoreListItem>(tempList);
  15:                 ItemComparer c = new ItemComparer();
  16:                 sortedList.Sort(c as IComparer<BookStoreListItem>);
  17:                 Collection.Set(context, sortedList as ICollection<BookStoreListItem>);
  18:             }
  19:         }
  20:     }
  21:     public class ItemComparer : IComparer<BookStoreListItem>
  22:     {
  23:         public int Compare(BookStoreListItem x, BookStoreListItem y)
  24:         {
  25:             // Handle null arguments
  26:             if (x == null && y == null)
  27:                 return 0;
  28:             if (x == null)
  29:                 return -1;
  30:             if (y == null)
  31:                 return 1;
  32:             // Perform comparison based on the priority
  33:             if (x.UnitPrice == y.UnitPrice)
  34:                 return 0;
  35:             if (x.UnitPrice > y.UnitPrice)
  36:                 return 1;
  37:             else
  38:                 return -1;
  39:         }
  40:     }
  41: }

This custom activity receives the collection as an input argument and return the same argument after sorting it. It expects a collection of BookStoreListItem classes .the overridden Execute() method of this activity takes a collection as both an input and output argument.The Sort() method of the List class is used to perform the sort, but you must supply a class that implements the IComparer interface because the standard implementation will not know how to sort BookStoreListItem objects. The IComparer interface provides a single method called Comparer (), which receives two objects (x and y) as input parameters. It returns 0 if the two objects are equal, 1 if x is greater than y, and -1 if x is less than y.

8- To use this custom activity, Open the Program.cs file and add the following activity definition to the collectionWF () method before the final writeline activity

   1: new SortBooksList
   2: {
   3:     Collection=myList
   4: },
   5: new WriteLine
   6: {
   7:     Text = "Books List sorted by Price"
   8: },
   9: new PrintBooksList
  10: {
  11:     Collection=myList
  12: },

If you run the application now you will find the following message printed

clip_image002[7]

if you have reviewed the printed lines in console, you will find the new books listed after line “books list sorted by price are order desc by price.

9- Searching in the collection, now we are going to use built in activity in Workflow Foundation 4.0 like ExistsInCollection, so we will check if the item found in the book list or not.

As the ExistsInCollection should iterate between books list items so it is require to use Equals() methods which mean we need to implement this method to our BookStoreListItem class, For our purposes, you should consider two items equal if they have the same name,To do that add the following list of code to BookStoreListItem class in program.cs file

   1: public override bool Equals(object obj)
   2: {
   3:     BookStoreListItem i = obj as BookStoreListItem;
   4:     if (i == null)
   5:         return false;
   6:     else
   7:     {
   8:         if (i.BookName == this.BookName)
   9:             return true;
  10:         else
  11:             return false;
  12:     }
  13: }
  14: public override int GetHashCode()
  15: {
  16:     return base.GetHashCode();
  17: }

The Equals() method cast the input object to a BookStoreListItem and returns True if the BookName property matches. When overriding the Equals() method, the compiler expects you to also override the GetHashCode() method. This implementation simply calls the base method

10- Now , we can use ExistsInCollection to do that add the following lines of code before the final writeline activity

   1: public override bool Equals(object obj)
   2:        {
   3:            BookStoreListItem i = obj as BookStoreListItem;
   4:            if (i == null)
   5:                return false;
   6:            else
   7:            {
   8:                if (i.BookName == this.BookName)
   9:                    return true;
  10:                else
  11:                    return false;
  12:            }
  13:        }
  14:        public override int GetHashCode()
  15:        {
  16:            return base.GetHashCode();
  17:        }
  18:

If you have run the application now you will see this line printed before workflow ended

“LINQ 4.0 Book has been added before”

11- Remove item from Collection, Workflow Foundation 4.0 has activity named RemoveFromCollection that is responsible for removing item from collection it very easy in implementation, we will use it to remove book named “LINQ 4.0“,to do that add the following line of code before the final writeline activity

   1: new WriteLine
   2: {
   3:     Text = "Removing LINQ 4.0 book from Books Store..."
   4: },
   5: new RemoveFromCollection<BookStoreListItem>()
   6: {
   7:     Collection = myList,
   8:     Item = new LambdaValue<BookStoreListItem>
   9:         (env => new BookStoreListItem("LINQ 4.0"))
  10: },
  11: new PrintBooksList()
  12: {
  13:     Collection = myList
  14: },

if you have run the application now you will see the following lines printed before workflow ended line

clip_image002[9]

12- Clearing the collection, Workflow Foundation 4.0 has built in activity to clear collection named ClearCollection to use this activity add the following lines of code before the final writeline activity

   1: new ClearCollection<BookStoreListItem>()
   2: {
   3:     Collection = myList
   4: },
   5: new PrintBooksList()
   6: {
   7:     Collection = myList
   8: },

If you have run the application now you will find line printed before workflow ended that says

“The book list is Empty”

Conclusion:

I was trying to learn you how WFF 4.0 are manipulation with collection,you can download The complete implementation of that post from here and you can return back to workflow posts list here

Back to other Workflow Foundation 4.0  posts

I Hope that helped

Advertisements

September 26, 2010 Posted by | .Net 2010 | , , , , , , | 1 Comment

Workflow Foundation 4.0 Custom activities

WFF 4.0 helps you to implement you own custom activity. sure creating custom activity is very important part that all Workflow developers are interested in.the new Workflow Foundation 4.0 give you two ways of generating custom activities.
As we need to prove concept only, my custom activity will be simple, just I am going to build custom activity that print the message “Hello FirstName Last Name” this custom activity taking two input parameters First Name and Last Name and return the full message,let’s see how to implement this simple example by Workflow Foundation 4.0.

Using Code Activity template

Code activity template give you advantage to inherit the codeactivity class and build your custom activity from scratch but the new Workflow Foundation helps you to do that in easy way, so to implement the new custom activity follow the following steps

1- Open Visual Studio 2010 and select file->new project->workflow->workflow consol application

2- In the name textbox write CustomactivitySample as the project name

3- After the solution has opened right click in the project name and select add new item that will open the list of items as shown in the below picture

clip_image002

select code activity and enter code activity name such as “HelloMsg
4- By default you with find the below list of code has been generated in your new file that named HelloMsg.cs

   1: public sealed class HelloMsg : CodeActivity
   2:     {
   3:         // Define an activity input argument of type string
   4:         public InArgument<string> Text { get; set; }
   5:         // If your activity returns a value, derive from CodeActivity<TResult>
   6:         // and return the value from the Execute method.
   7:         protected override void Execute(CodeActivityContext context)
   8:         {
   9:             // Obtain the runtime value of the Text input argument
  10:             string text = context.GetValue(this.Text);
  11:         }
  12:     }

5- Now we are going to add our code for printing hello message

– First we will prepare the activity parameters, so replace line no 4 in the above codes list with the following list of codes

   1: public InArgument<string> FirstName { get; set; }
   2: public InArgument<string> LastName { get; set; }
   3: public OutArgument<string> HelloMessgae { get; set; }

As shown in the above codes list we have declared two input parameters first name and last name and one output parameter for returning the complete hello message.

– The last step for implementing this custom activity is to add code for using input parameters and concatenating it to return the complete hello message, so please replace line 10 at the codes list in step 4 with the following list of codes

   1: string fname = context.GetValue(this.FirstName);
   2: string lname = context.GetValue(this.LastName);
   3: string completeMsg = " Hello " + fname +" "+ lname;
   4: context.SetValue(this.HelloMessgae, completeMsg);

6- Build the project to refresh the toolbar, and you will notice new activity hellomsg activity has been added to the toolbar.

7- Open Workflow1.xaml in designer view and drag sequence activity then drag hellomsg and writeline activity by ordered in the new added sequence activity

8- Create variable named fullname and has data type string from the variables window at bottom of the workflow1 designer

9-Open the writeline property windows and set the text property to the new created variable name in the previous step

10- Open the hellomsg property window and set it is properties as follow:

a- FirstName: “Mohammed”

b- Last Name: “Atef”

c- HelloMessage: fullname which added in step no 8

Finally run the application you will see this message in the console window

“Hello Mohammed Atef”

Using Activity

Using the activity you can create your own activity and use it in another work flow as independent activity and you can pass parameters between your activity and the main workflow designer

This kind of activities is very simple as you are using the workflow designer with all toolbar activities available to implement you custom activity.

We are going to do the same business scenario in the previous example but we will add the following message before the hello message “Custom Activity using Designer.” this only to determine the message printed for each custom activity.

Now , to implement the new custom activity follow the following steps

1- Write click into the project name and select add new item then select activity icon from the windows as shown in picture below

clip_image002[4]

name that activity hellomsgActivity.xaml

2- Drag sequence activity to the new created activity named hellomsgActivity.xaml and then drag writeline activity into the sequence activity

3- Add two arguments from arguments window below the designer of that activity named hellomsgActivity.xaml

4- Write the following line into the text property of the writeline activity

“Custom Activity using Designer: Hello Mr. ” + FName + LName

5- Build the application

6- Open the main workflow1.xaml in design mode and drag hellomsgActivity activity from the toolbar

7- Open the hellomsgActivity property window and set it is properties as follows

a- FName:”Mohammed”

b-LName:”Atef”

Now Run the application you will find the following messages are printed

Hello Mohammed Atef”

Custom Activity using Designer: Hello Mr. Mohammed Atef”

Now we have finished this example and the main workflow1.xaml should be like the following picture below

clip_image002[6]

You can also download the complete example by source code from here.
Back to other Workflow Foundation 4.0  posts

I hope that helped.

September 26, 2010 Posted by | .Net 2010 | , , , , , | 3 Comments

Workflow Foundation 4.0 Tracking

Introduction

This post will guide you to use extensions for tracking Workflow events while it is executing the defined activities.This is useful for monitoring a workflow’s execution and for triggering external processing.

Tracking
In WF 4.0, tracking is accomplished through tracking participants, which are extensions that are derived
from the TrackingParticipant abstract class.
First of all to implement tracking extensions you need to inherit TrackingParticipant class and overrides the Track() method, which is where most of the work is done. When a trackable event occurs, the workflow instance will enumerate all the extensions and will call the Track() method in any that are derived from the TrackingParticipant base class.
A TrackingRecord is passed into the Track() method. This is an abstract class; the actual instance passed
in will be one of the following classes, which are derived from the TrackingRecord class:
WorkflowInstanceRecord contains data about the workflow instance.
You can use this class to print the Workflow instance ID and Workflow instance state as shown in the below list of codes:

   1: WorkflowInstanceRecord instance = record as WorkflowInstanceRecord;
   2: if (instance != null)
   3: {
   4: Console.WriteLine(String.Format(" InstanceID: {0} State: {1}",instance.InstanceId, instance.State));
   5: }

BookmarkResumptionRecord contains data about the bookmark being resumed.

You can use this class to print the book mark name as shown in the below list of codes:

   1: BookmarkResumptionRecord bookmark = record as BookmarkResumptionRecord;
   2: if (bookmark != null)
   3: {
   4: Console.WriteLine(String.Format(" Bookmark {0} resumed",bookmark.BookmarkName));
   5: }

ActivityStateRecord contains data about a specific activity.

You can use this class to print information about activities hosted in the Workflow instance as shown in the below list of codes:

   1: ActivityStateRecord activity = record as ActivityStateRecord;
   2: if (activity != null)
   3: {
   4: IDictionary<String, object> variables = activity.Variables;
   5: StringBuilder s = new StringBuilder();
   6: if (variables.Count > 0)
   7: {
   8: s.AppendLine(" Variables:");
   9: foreach (KeyValuePair<string, object> v in variables)
  10: {
  11: s.AppendLine(String.Format(" {0} Value: [{1}]",
  12: v.Key, v.Value));
  13: }
  14: }
  15: Console.WriteLine(String.Format(" Activity: {0} State: {1} {2}",
  16: activity.Activity.Name, activity.State, s.ToString()));
  17: }

CustomTrackingRecord contains user-defined data.

You can use this class to print about user-defined data as shown in the below list of codes

   1: CustomTrackingRecord user = record as CustomTrackingRecord;
   2: if ((user != null) && (user.Data.Count > 0))
   3: {
   4: Console.WriteLine(String.Format(" User Data: {0}", user.Name));
   5: foreach (string data in user.Data.Keys)
   6: {
   7: Console.WriteLine(String.Format(" {0} : {1}", data, user.Data[data]));
   8: }
   9: }

To use the tracking extension you should add the tracking extension to the Workflow instance as shown in the below list of codes

   1: i.Extensions.Add(_tracking);
   2: //where i is an instance of WorkflowApplication  
   3: //and _tracking is an instance of class that inherits TrackingParticipant class

Then you should set up the tracking extensions participants by using TrackingProfile collections, A TrackingProfile defines a collection of queries that specify which events are to be tracked by the associated tracking participant. These queries are used to determine if an event is trackable. The queries are stored in the Queries property, which is a collection of classes derived from the abstract TrackingQuery class. There are four derived classes that correspond to the four types of tracking records:

WorkflowInstanceQuery

A WorkflowInstanceQuery is used to define the workflow instance events that should be tracked. These

are the process states that occur at the instance level such as Started, Completed, Unloaded, and so on, To do that you can write the below list of codes:

   1: TrackingProfile = new TrackingProfile()
   2: {
   3:     Name = "TrackingProfileName",
   4:     Queries =
   5:     {
   6:         // For instance data, only track the started and completed events
   7:         new WorkflowInstanceQuery()
   8:         {
   9:             States = { WorkflowInstanceStates.Started,WorkflowInstanceStates.Completed },
  10:         }
  11: }

BookmarkResumptionQuery

In a BookmarkResumptionQuery, you specify the name of the bookmark that you want to track whenever it is resumed. You can specify only a single bookmark in a query. If you want to track multiple bookmarks,

you should create multiple queries—one for each bookmark, To do that you can write the below list of codes:

   1: TrackingProfile = new TrackingProfile()
   2: {
   3:     Name = "TrackingProfileName",
   4:     Queries =
   5:     {
   6:         new BookmarkResumptionQuery()
   7:                       {
   8:                           Name = "GetAssignment"
   9:                       }
  10: }

ActivityStateQuery

An ActivityStateQuery class specifies both the Name of the activity and the State collection (events) that

should be tracked. You can specify an asterisk (*) for either, which indicates that all activities and/or

states should be tracked, To do that you can write the below list of codes:

   1: TrackingProfile = new TrackingProfile()
   2:                 {
   3:                     Name = "ListBoxTrackingProfile",
   4:                     Queries =
   5:                     {
   6:                         // For activity data, track all states of the InvokeMethod
   7:                        new ActivityStateQuery()
   8:                        {
   9:                            ActivityName = "InvokeMethod",
  10:                            States = { "*" },
  11:                        }
  12:                     }
  13: }

CustomTrackingQuery

The CustomTrackingQuery specifies the ActivityName, which indicates the activity that generated the

CustomTrackingRecord and the Name property, which indicates the name given to the CustomTrackingRecord,You can specify an asterisk for either (or both) as the example, above does. When

both are set to *, it indicates that all user events should be tracked, you can do that by typing the below of codes:

   1: TrackingProfile = new TrackingProfile()
   2:                 {
   3:                     Name = "ListBoxTrackingProfile",
   4:                     Queries =
   5:                     {
   6:                         new CustomTrackingQuery()
   7:                         {
   8:                             Name = "*",
   9:                             ActivityName = "*"
  10:                         }
  11:                     }
  12: }

In this post we have understood the Tracking extension and we have learned how to use it also.now you can visit the orher posts about Workflow Foundation for here

I hope that helped.

September 26, 2010 Posted by | .Net 2010 | , , , , , , | 2 Comments

Workflow Foundation 4.0 Extensions

Introduction

Workflow foundation Extensions allow you to add configurable behavior to a workflow solution. The activities that you include in your workflow define the steps that are performed, while the extensions provide the operating environment that these activities are executed in, the persistence extension is not aware of what activities are executed; the extension however, provides the ability to persist those activities (whatever they might be) to a durable store.

SQL Persistence Extension

There are two key aspects of extensions that make then extremely useful. First, as was inferred
earlier, they are configurable. For example, the persistence provider that was used SqlWorkflowInstanceStore was designed to use a SQL Server database. Without changing the
application or the workflow definition.
The second aspect of extensions is that they can be accessed both from the application as well as the
workflow activities. This provides a convenient tool for sharing information between the application and
the workflow.

To use SQL Persistence you need to declare a reference to the InstanceStore class that will be used to persist and load the workflow instances :

   1: private InstanceStore _instanceStore;

Then add you need to Loaded event handler and configures the store to do that you need to write the following code

   1: _instanceStore = new SqlWorkflowInstanceStore(_connectionString);
   2: InstanceView view = _instanceStore.Execute(_instanceStore.CreateInstanceHandle(),
   3: new CreateWorkflowOwnerCommand(),TimeSpan.FromSeconds(30));
   4: _instanceStore.DefaultInstanceOwner = view.InstanceOwner;

where the _connectionstring is the DB sql connection string used for your SQL Persistence.above code has an InstanceStore that is an abstract class from which all persistence providers are derived. An instance of the concrete class SqlWorkflowInstanceStore is created, passing the connection string in the constructor.

The parameters to the Execute() method are a handle (provided by InstanceStore ), a command, and a

timeout value. It returns an InstanceView class, which is roughly analogous to a connection handle.

Now you need to setup The Workflow persistence, to do that add the following codes listed below

   1: i.InstanceStore = _instanceStore;//where i is and instance of WorkflowApplication
   2: i.PersistableIdle = (waiea) => PersistableIdleAction.Unload;
   3: i.Run();

The above code configures the workflow instance to be persisted. First, it sets the InstanceStore

property using the reference created as described early. It then provides an event handler for

the PersistableIdle event, which tells the instance to unload itself from memory. It is persisted to the

database prior to being unloaded.

Custom Extensions

here we will learn how to build a custom extension and how to use it in you Workflow. we are going to build simple custom extension that used to store the connection string, Instead of passing the connection string as an input argument, any activity that needs the connection string can access it from this extension.

Assume that we will create class called  that hold the custom extension and implemented as shown in list below

   1: using System;
   2: public class ConStringExtension
   3:     {
   4:         private string _connectionString = "";
   5:
   6:         public DBExtension(string connectionString)
   7:         {
   8:             _connectionString = connectionString;
   9:         }
  10:
  11:         public string ConnectionString { get { return _connectionString; } }
  12:     }

The above code simply defines a private member that holds the connection string. The value of this string

is passed in the class constructor. A public property is provided for accessing this string.To add the new Custom extension to you Workflow instance add the following code

   1: ConStringExtension _dbExtension = new ConStringExtension(_connectionString);
   2: i.Extensions.Add(_dbExtension);

Finally to use this custom extension into code activity add the following line

   1: ConStringExtension ext = context.GetExtension<ConStringExtension>();

I hope you have understand Workflow extensions well ,now you can check other posts about work flow here

I hope that helped.

September 26, 2010 Posted by | .Net 2010 | , , , , , | 1 Comment

Workflow Foundation 4.0

The new Workflow foundation comes with .Net Framework 4.0 that supports building and running the next generation of applications and services. The key components of the .NET Framework are the common language runtime (CLR) and the .NET Framework class library, which includes ADO.NET, ASP.NET, Windows Forms, and Windows Presentation Foundation (WPF), by the way all Visual Studio 2010 IDE are build in XAML language that provides a managed execution environment, simplified development and deployment, and integration with a wide variety of programming languages.

In version 4 of the Microsoft® .NET Framework, Windows Workflow Foundation introduces a significant amount of change from the previous versions of the technology that shipped as part of .NET 3.0 and 3.5.

The significant changes made were necessary to provide the best experience for developers adopting WF and to enable WF to continue to be a strong foundational component that you can build on in your applications.

I have wrote this article to give you a start point to understand and study Workflow Foundation 4.0, so I am going to write series of posts about WFF 4.0 as found in the below below List

I hope that helped

September 20, 2010 Posted by | .Net 2010 | , , , , , | 6 Comments

What’s new in Workflow Foundation 4.0

The New Workflow Foundation 4.0 introduces a significant amount of change from the previous versions of the technology that shipped as part of .NET 3.0 and 3.5. so let’s go quickly to see these new features

  • Designers are built in XAML The designer is based on Windows Presentation Foundation (WPF),so it is taking full advantage of the rich user experience one can build with the declarative UI framework.  Activity developers will use XAML to define the way their activities look and interact with users in a visual design environment.  In addition, it enables non-developers to view and interact with your workflows is now much easier as XAML language is written in XML language that give any non-developers ability to read and understand it.

    For example if you have created new project of Console Workflow and dragged a WriteLine activity in the designer and select the code view you will find the following list of XAML codes

       1: <Activity mc:Ignorable="sap" x:Class="WorkflowConsoleApplication1.Workflow1" sap:VirtualizedContainerService.HintSize="251,240" mva:VisualBasic.Settings="Assembly references and imported namespaces for internal implementation" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Xml" xmlns:s3="clr-namespace:System;assembly=System.Core" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
       2: <WriteLine
       3: sad:XamlDebuggerXmlReader.FileName="C:\Temp\DotNet4\WorkflowConsoleApplication1\Workflow1.xaml"
       4: sap:VirtualizedContainerService.HintSize="211,200" />
       5: </Activity>

    I think any non-developer can understand the above list of XAML code

  • Different project templates The new Workflow Foundation 4.0 comes with new project templates as shown in below pictureclip_image002

    The above picture shows only four project templates of Workflow Foundation 4.0 that leads you to simplify project templates for developer. The first project template Activity Designer Library let you create you custom Workflow Foundation Activity with designer, while the second project template leads you to create your custom activity by inheriting the CodeActivity class and the third project template leads you to build new WCF Workflow Service and we are going to explain this project template deeply in another post later finally the last project type help you for creating Console application that contain Workflow Activities.

    If you reviews the below pictures that has list of project template found for Workflow Foundation 3.5 you will understand that new Workflow Foundation 4.0 has summarized and compressed the project templates in better way.

    clip_image002[7]

  • Variable and parameters new windows in the WFF IDE Workflow Foundation 4.0 introduces a helpful window for creating variables and parameters to your Workflow in easy way, the below two pictures show you the new windows generated for defining variables and parameters

    clip_image002[9]

    clip_image002[11]

    First Picture show you how to declare variable to you workflow, as shown there you can define the DataType of you variable, default value and the scope of a variable either the entire workflow or just a specific activity or its children.

    Second picture show you how to define arguments by specifying its name, direction(In,Out,In/Out), argument type and default value.

    If you have used Workflow Foundation 3.5 before you should understand what Workflow Foundation 4.0 has introduced to you for declaring variables and arguments as in WFF 3.5 you should write the following list of codes to define variable

   1: public static DependencyProperty MessageProperty =
   2:     DependencyProperty.Register("Message", typeof(string), typeof(CustomActivity));
   3:
   4:         [DescriptionAttribute("Message")]
   5:         [BrowsableAttribute(true)]
   6:         [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
   7:         public string Message
   8:         {
   9:             get
  10:             {
  11:                 return ((string)(base.GetValue(MessageProperty)));
  12:             }
  13:             set
  14:             {
  15:                 base.SetValue(MessageProperty, value);
  16:             }
  17:         }
  18:

The above bulk of code writes only for defining variable Named message of type string

  • Windows Communication Foundation (WCF) Integration

    Workflow Foundation 4.0 introduce creating services and consuming or coordinating service interactions.  A great deal of effort went into enhancing the integration between WCF and WF.  New messaging activities, message correlation, and improved hosting support, along with fully declarative service definition are the major areas of improvement, We will go deeply throw WCF integration with the new WF in another post later.

  • New built in Activity The new Workflow Foundation 4.0 has a lot of built in activities as follows- New activities for manipulating data such as Assign and collection activities such as AddToCollection.

    – New flow control activities, such as DoWhile, TryCatch, ForEach, Switch, and ParallelForEach.

    – Activities for controlling transactions, such as TransactionScope and Compensate.

    – New messaging activities such as SendContent and ReceiveReply.

    Most of these Activities will be explained in the next post for WFF 4.0 toolbar.

    Back to other Workflow Foundation 4.0  posts

I Hope that Helped

September 20, 2010 Posted by | .Net 2010 | , , , , , | 1 Comment