<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>knom's developer corner : WF</title><link>http://blogs.msdn.com/knom/archive/tags/WF/default.aspx</link><description>Tags: WF</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Inside Workflow Foundation Activities</title><link>http://blogs.msdn.com/knom/archive/2008/03/01/inside-workflow-foundation-activities.aspx</link><pubDate>Sat, 01 Mar 2008 22:17:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7981110</guid><dc:creator>knom</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/knom/comments/7981110.aspx</comments><wfw:commentRss>http://blogs.msdn.com/knom/commentrss.aspx?PostID=7981110</wfw:commentRss><description>&lt;p&gt;Activities are the heart of WF. Together they form workflows, control the flow or do loops.&lt;/p&gt; &lt;p&gt;They can either be &lt;strong&gt;&lt;em&gt;simple and atomic&lt;/em&gt;&lt;/strong&gt; or&lt;strong&gt;&lt;em&gt; composite&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Simple activities&lt;/strong&gt; can do one thing as calling a database or web service, terminating the workflow or something else.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Composite&lt;/strong&gt; &lt;strong&gt;activities&lt;/strong&gt; consist of other activities - they have children within. If the "parent" composite activity is executed, it controls which children are executed in which order. The simplest composite activity, the sequence executes all it's children in a sequential way. A parallel activity consists of several sequences executes at the same time. But there are even more complex composite activities like IF statements, or loops. Even the entire workflow (either sequential or state machine based) is nothing more than a special activity with custom logic and additional properties.&lt;/p&gt; &lt;p&gt;Regardless of whether it is a simple or composite activity, each activity (at least somewhere above in the inheritance tree) inherits of &lt;strong&gt;&lt;em&gt;Activity&lt;/em&gt;&lt;/strong&gt; class.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;MyActivity&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;Activity
&lt;/span&gt;{
    &lt;span style="color: rgb(0,0,255)"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;override&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; Initialize(&lt;span style="color: rgb(43,145,175)"&gt;IServiceProvider&lt;/span&gt; provider);

    &lt;span style="color: rgb(0,0,255)"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;override&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ActivityExecutionStatus&lt;/span&gt; Execute(&lt;span style="color: rgb(43,145,175)"&gt;ActivityExecutionContext&lt;/span&gt; executionContext);
    &lt;span style="color: rgb(0,0,255)"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;override&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ActivityExecutionStatus&lt;/span&gt; Cancel(&lt;span style="color: rgb(43,145,175)"&gt;ActivityExecutionContext&lt;/span&gt; executionContext);
    &lt;span style="color: rgb(0,0,255)"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;override&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ActivityExecutionStatus&lt;/span&gt; HandleFault(&lt;span style="color: rgb(43,145,175)"&gt;ActivityExecutionContext&lt;/span&gt; executionContext,
                                                                &lt;span style="color: rgb(43,145,175)"&gt;Exception&lt;/span&gt; exception);
    &lt;span style="color: rgb(0,0,255)"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;override&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; Uninitialize(&lt;span style="color: rgb(43,145,175)"&gt;IServiceProvider&lt;/span&gt; provider);
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;What you get, is basic virtual methods, which you can override to provide the behaviour of your activity for this state.&lt;/p&gt;
&lt;p&gt;Speaking of states - each activity implements a finite state machine.&lt;a href="http://blogs.msdn.com/blogfiles/knom/WindowsLiveWriter/InsideWorkflowFoundationActivities_11D37/image_2.png"&gt;&amp;nbsp;&lt;/a&gt;That means the activity is guaranteed to be in one of the following states:&lt;a href="http://blogs.msdn.com/blogfiles/knom/WindowsLiveWriter/InsideWorkflowFoundationActivities_11D37/image_4.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="243" alt="image" src="http://blogs.msdn.com/blogfiles/knom/WindowsLiveWriter/InsideWorkflowFoundationActivities_11D37/image_thumb_1.png" width="644" border="0"&gt;&lt;/a&gt;  State transitions may occur only in the directions of the arrows. White arrows are runtime-, yellow ones developer initiated.&lt;/p&gt;
&lt;p&gt;This activity automaton displays the entire lifecycle of an activity:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;At creation of the workflow &lt;em&gt;&lt;strong&gt;Initialize()&lt;/strong&gt; &lt;/em&gt;is called on all activities. They are afterwards placed in the &lt;strong&gt;&lt;em&gt;Initialized &lt;/em&gt;&lt;/strong&gt;state.&lt;/li&gt;
&lt;li&gt;The activity is placed into &lt;strong&gt;&lt;em&gt;Executing&lt;/em&gt;&lt;/strong&gt; state and it's &lt;strong&gt;&lt;em&gt;Executing()&lt;/em&gt;&lt;/strong&gt; method is called. Within it the activity's actual work is done.&lt;/li&gt;
&lt;li&gt;If an error occurs, the activity &lt;em&gt;automatically &lt;/em&gt;transitions into &lt;strong&gt;&lt;em&gt;Faulting,&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;HandleFault()&lt;/em&gt;&lt;/strong&gt; is called.&lt;/li&gt;
&lt;li&gt;Executing activities can be &lt;strong&gt;canceled &lt;/strong&gt;&lt;em&gt;by other activities &lt;/em&gt;to stop their execution.&lt;/li&gt;
&lt;li&gt;Finally if all the execution, cancellation or fault handling work is done, the activity is closed &lt;em&gt;by the developer&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Additionally there is the possibility to "undo" already executed activities. For that situation you can implement the &lt;strong&gt;&lt;em&gt;ICompensatableActivity&lt;/em&gt;&lt;/strong&gt; interface, which defines a &lt;strong&gt;&lt;em&gt;Compensate()&lt;/em&gt;&lt;/strong&gt; method. This method is called in the &lt;strong&gt;&lt;em&gt;Compensating&lt;/em&gt;&lt;/strong&gt; state and allows you to provide custom undo logic.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;So to write you custom little activity, just inherit of the Activity base class and override the suitable methods for the states you want to provider logic for. To pass data from outside into the activity you can use &lt;strong&gt;&lt;em&gt;DependencyProperties&lt;/em&gt;&lt;/strong&gt;, a new concept in .NET 3.0 which are also used with WPF.&lt;/p&gt;
&lt;p&gt;Here is a sample of a ConsoleWritelineActivity:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ConsoleWriteline&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;Activity
&lt;/span&gt;{
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;DependencyProperty&lt;/span&gt; OutputProperty = &lt;span style="color: rgb(43,145,175)"&gt;DependencyProperty&lt;/span&gt;.Register(&lt;span style="color: rgb(163,21,21)"&gt;"Output"&lt;/span&gt;,
        &lt;span style="color: rgb(0,0,255)"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;), &lt;span style="color: rgb(0,0,255)"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;ConsoleWriteline&lt;/span&gt;));

    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; Output
    {
        &lt;span style="color: rgb(0,0,255)"&gt;get
&lt;/span&gt;        {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; ((&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;)(&lt;span style="color: rgb(0,0,255)"&gt;base&lt;/span&gt;.GetValue(&lt;span style="color: rgb(43,145,175)"&gt;ConsoleWriteline&lt;/span&gt;.OutputProperty)));
        }
        &lt;span style="color: rgb(0,0,255)"&gt;set
&lt;/span&gt;        {
            &lt;span style="color: rgb(0,0,255)"&gt;base&lt;/span&gt;.SetValue(&lt;span style="color: rgb(43,145,175)"&gt;ConsoleWriteline&lt;/span&gt;.OutputProperty, &lt;span style="color: rgb(0,0,255)"&gt;value&lt;/span&gt;);
        }
    }
    &lt;span style="color: rgb(0,0,255)"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;override&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ActivityExecutionStatus&lt;/span&gt; Execute(&lt;span style="color: rgb(43,145,175)"&gt;ActivityExecutionContext&lt;/span&gt; executionContext)
    {
        &lt;span style="color: rgb(43,145,175)"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt;.Output);
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ActivityExecutionStatus&lt;/span&gt;.Closed;
    }
}&lt;/pre&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7981110" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/knom/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/knom/archive/tags/WF/default.aspx">WF</category></item><item><title>Advanced Workflow Foundation - MSDN Briefing</title><link>http://blogs.msdn.com/knom/archive/2008/02/29/advanced-workflow-foundation-msdn-briefing.aspx</link><pubDate>Fri, 29 Feb 2008 21:04:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7955042</guid><dc:creator>knom</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/knom/comments/7955042.aspx</comments><wfw:commentRss>http://blogs.msdn.com/knom/commentrss.aspx?PostID=7955042</wfw:commentRss><description>&lt;p&gt;This week I had a session about advanced topics of Windows Workflow Foundation.&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/knom/WindowsLiveWriter/AdvancedWorkflowFoundationMSDNBriefing_10C49/image_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="259" alt="image" src="http://blogs.msdn.com/blogfiles/knom/WindowsLiveWriter/AdvancedWorkflowFoundationMSDNBriefing_10C49/image_thumb.png" width="260" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Some features I covered were&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Workflow Execution Internals&lt;/li&gt; &lt;li&gt;External Services &amp;amp; Communication&lt;/li&gt; &lt;li&gt;Activity Execution Context&lt;/li&gt; &lt;li&gt;Persistence&lt;/li&gt; &lt;li&gt;Workflow States&lt;/li&gt; &lt;li&gt;Fault Handling&lt;/li&gt; &lt;li&gt;Transactions&lt;/li&gt; &lt;li&gt;Tracking&lt;/li&gt; &lt;li&gt;Advanced Authoring&lt;/li&gt; &lt;li&gt;Dynamic Updates&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Feel free to download the slides and play around with the demos!&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://knom.members.winisp.net/downloads/Advanced_WF.pdf" target="_blank"&gt;Slides&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://knom.members.winisp.net/downloads/Advanced_WF_Demos.zip" target="_blank"&gt;Demos&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7955042" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/knom/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/knom/archive/tags/Work/default.aspx">Work</category><category domain="http://blogs.msdn.com/knom/archive/tags/Events/default.aspx">Events</category><category domain="http://blogs.msdn.com/knom/archive/tags/WF/default.aspx">WF</category></item></channel></rss>