• mwinkle.blog

    VS 2008 Beta 2 Shipped : 0 to Workflow Service in 60 seconds

    • 2 Comments

    So, per Soma's blog, this great Channel9 video, and a bunch of other places, VS 2008 Beta 2 is available for download (go here).

    Others are covering their favorite feature in depth, I want to cover one of mine: the WCF test client, which I will show by way of creating a Workflow Service application.

    Real quick, for those of you who didn't read the readme file, I know sometimes you just forget, there is an important note regarding how to get  this to work (out of the box you will probably get an exception in svcutil.exe).

    Running a WCF Service Library results in svcutil.exe crashing and the test form not working

    Running a WCF Service Library starts the service in WcfSvcHost and opens a test form to debug operations on the service.  On the Beta2 build this results in crash of svcutil.exe and the test form doesn’t work due to a signing problem.

    To resolve this issue

    Disable strong name signing for svcutil.exe by opening a Visual Studio 2008 Beta2 Command Prompt. At the command prompt run: sn –Vr “<program files>\Microsoft SDKs\Windows\v6.0A\Bin\SvcUtil.exe”  (replace <program files> with your program files path – ex: c:\Program Files)

    Fire up VS 2008, create a new Sequential Workflow Service Library project:

    image

    This creates a basic Sequential workflow with a Receive activity

    image

    It also creates an app.config and IWorkflow1.cs

    image

    IWorkflow1.cs contains the contract our service is going to implement:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    
    namespace WFServiceLibrary1
    {
        // NOTE: If you change the interface name "IWorkflow1" here, 
        // you must also update the reference to "IWorkflow1" in App.config.
        [ServiceContract]
        public interface IWorkflow1
        {
            [OperationContract]
            string Hello(string message);
        }
    }

    Now, we can modify this as needed, or we can delete it and create the contract as part of the Receive activity, see my previous post here on the topic.

    Return to the workflow and take a quick look at the properties of the Receive activity, and note that the parameters for the method (message and (returnValue)) have already been promoted and bound as properties on the workflow, that saves us a quick step or two:

    image

    Drop a code activity in the Receive shape, and double click to enter some code:

    image

    private void codeActivity1_ExecuteCode(object sender, EventArgs e)
    {
        returnValue = String.Format("You entered '{0}'.", inputMessage);
    }

    Now, we're pretty much there, but let's take a quick look at the app.config

    <service name="WFServiceLibrary1.Workflow1" behaviorConfiguration="WFServiceLibrary1.Workflow1Behavior">
      <host>
        <baseAddresses>
          <add baseAddress="http://localhost:8080/Workflow1" />
        </baseAddresses>
      </host>
      <endpoint address=""
                binding="wsHttpContextBinding"
                contract="WFServiceLibrary1.IWorkflow1" />
      <endpoint address="mex" 
                binding="mexHttpBinding" 
                contract="IMetadataExchange" />
    </service>

    We're going to use the wsHttpContextBinding, which you can think of as the standard wsHttpBinding with the addition of the Context channel to the channel stack.  Also note, we can right click the config and open it in the WCF config editor, slick!

    image

    Let's hit F5.  We build, do a little bit of processing and up pops the WCF test client.  You may also note this little pop up from your task tray:

    image

    What's this, the "autohosting" of your service, just like you get with ASP.NET on a machine.  This saves me the trouble of having to write a host as well as my service when I just want to play around a bit.  The test client looks like this:

    image

    Double click on the hello operation and fill in a message to send to the service:

    image

    Clicking "Invoke" will invoke the service, which will soon return with the value we hope to see.  Sure enough, after a bit of chugging along, this returns:

    image

    Finally, let's hit the XML tab to see what's in there, and we see it is the full XML of the request and the response.  There's an interesting little tidbit in the header of the response:

    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" 
    xmlns:a="http://www.w3.org/2005/08/addressing" 
    xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
      <s:Header>
        <a:Action s:mustUnderstand="1" u:Id="_2">
           http://tempuri.org/IWorkflow1/HelloResponse
         </a:Action>
        <a:RelatesTo u:Id="_3">urn:uuid:3f5b7eb5-cc35-4b01-b345-92f6edf728d7</a:RelatesTo>
        <Context u:Id="_4" xmlns="http://schemas.microsoft.com/ws/2006/05/context">
          <InstanceId>fc0f47fd-dd7b-4030-9883-acbf358583c3</InstanceId>
        </Context>

    This is the context token that lets me know how to continue conversing with this workflow.  In the test client, I can't find a way to attach it to a subsequent request, meaning we can't use the test client for testing multiple steps through a workflow, but this new feature lets me get up and running, verify connectivity, and be able to set breakpoints and debug my workflow service, which is pretty cool.

    I've posted the following video on c9 as a screencast, which I will try to do with my subsequent blog postings.

  • mwinkle.blog

    Introducing the Windows Server 2008 Developer Training Kit

    • 0 Comments

    Finally, a post of mine without code, haven't had one of those in a while.

    Through some interesting organizational hierarchies, I actually report up through the Longhorn Server, strike that, Windows Server 2008 evangelism team, and every now and then do deliver some content that is relevant to Windows Server 2008 (there, got it right that time).

    Check out this Developer Training Kit we just released over on James' blog.

    This thing contains about 15 presentations on topics relevant to Windows Server 2008 development, including some cool stuff on TxF (Transactional File System) (and of course, WF and WCF.

    Check it out, here.

  • mwinkle.blog

    N of M Question (Why Use ActivityExecutionContextManager?)

    • 1 Comments

    In this post, mstiefel  asked the following:

    # re: Implementing the N of M Pattern in WF

    Since you are not looping, do you have to use the ActivityExecutionContextManager to generate a new context for the child activities? Couldn't you use the context passed into the Execute method?

    Friday, July 06, 2007 7:54 PM by mstiefel

    If I were creating a parallel activity, and simply wanted to execute a number of distinct child activities, I would just use the passed in context as you suggest to schedule execution of each of the activities.  The difference here is subtle, and that is I don't have distinct child activities, I have one child activity which I need to clone m times and execute those cloned children separately.  The need to create the context is so that each one of those clones maintains it's own execution context, what variables are where, who is in what state, etc.  This is important while executing, and while after completion in the need where I want to compensate for the individual activities.

    This line

    ActivityExecutionContext newContext = aecm.CreateExecutionContext(this.Activities[0]);

    is what will cause the activity to be cloned, allowing me to schedule the execution of the clone, and not the template activity (which, incidentally, will never be scheduled, leaving me with m+1  copies of the activity.  This is the same behavior that I get in a While or a Replicator (or the CAG, depending upon how it is configured).  A state machine workflow will do a similar thing as I may re-enter a state multiple times. 

    If, instead of allowing a user to specify the list of approvers and dynamically creating the activities, I designed it so that a user would have to drop and configure an activity for each approval (similar to the parallel activity), I would have used code like this:

    // Code to schedule distinct activities in parallel, aka code similar to the parallel activity
    protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
    {
            foreach (Activity activity in ChildActivities)
            {
                // i is some counter I use to track how many branches there are so I know when
                // I am done
                i++;
                // I'm interested in what happens when this guy closes.
                activity.RegisterForStatusChange(Activity.ClosedEvent, this);
                executionContext.ExecuteActivity(activity);
            }
            return ActivityExecutionStatus.Executing;
    }
    

Page 1 of 1 (3 items)