March 2008 - Posts

The new ReceiveActivity and SendActivity that marry Windows Workflow Foundation (WF) and Windows Communication Foundation (WCF) are really cool Smile. Getting started is easy because a new Sequential Workflow Service Library, found under WCF instead of Workflow in VS2008, uses nice defaults for everything. But sooner or later you need to change these defaults and you need to know what can be done and what can't.

When you want to use the new ReceiveActivity in a workflow you need to use a compatible WCF binding. The reason for this requirement is that the conversation context, see this blog post, is part of the message and needs to be retrieved and returned. The following code returns a list of all WCF binding and how they are composed:

Sub Main()

Dim assemblies As New List(Of Assembly)()

' .NET 3.0

assemblies.Add(GetType(ServiceHost).Assembly)

' .NET 3.5

assemblies.Add(GetType(WorkflowServiceHost).Assembly)

assemblies.Add(GetType(WebServiceHost).Assembly)

 

Dim query = From assembly In assemblies _

From type In assembly.GetTypes() _

Where type.IsSubclassOf(GetType(Binding)) _

AndAlso Not type.IsAbstract _

AndAlso type.IsPublic _

Order By type.Name _

Select type

 

PrintBinding(query.ToList)

 

Console.ReadLine()

End Sub

 

Private Sub PrintBinding(ByVal types As List(Of Type))

For Each type In types

Console.WriteLine(type.FullName)

Try

Dim binding As Binding = _

CType(Activator.CreateInstance(type), Binding)

Dim elements = binding.CreateBindingElements

For Each element In elements

Console.WriteLine(vbTab + element.GetType().FullName)

Next

Catch ex As Exception

Console.WriteLine(ex.Message)

End Try

Console.WriteLine()

Next

End Sub

 

The classes responsible for inserting and removing these conversation tokens are ContextRequestChannel and ContextReplyChannel and they are instantiated by the ContextBindingElement. So seems we are restricted to using BasicHttpContextBinding, NetTcpContextBinding or WSHttpContextBinding.

So it seems we cannot use NetMsmqBinding which is a shame because one way reliable messaging is the perfect fit for workflow as far as I am concerned. Well not quite so fast because we still have the CustomBinding where we can configure the stack just the way we want right?

Yeah we do but there is a problem Sad. It turns out the ContextBinding requires a channel with an IReplyChannel interface and the NetMsmqBinding actually implement an IInputChannel or an IOutputChannel. Which one actually depends if you are the client or the service.

And thinking about how WF/WCF conversations works this restriction makes sense. After all a ReceiveActivity is called without a context in order to create a new workflow, assuming the CanCreateInstance property equals true, and returns the workflow instanceId in the context as part of the response. This design kind of rules out one-way messages and thereby NetMsmqBinding.

Now this sucks big time if you ask me Sad. I would much rather have seen that you could specify the instanceId of the workflow to be created, just as you can with the WorkflowRuntime.CreateWorkflow() where a number of the overloads let you specify the workflows instanceId. I suppose it is possible to create a different context binding but that would be quite some work and, I assume, duplicate a lot of code already written my Microsoft. So let's hope they see the light and add MSMQ/ReceiveActivity intergration.

 

Enjoy!

www.TheProblemSolver.nl
http://wiki.WindowsWorkflowFoundation.eu

with no comments
Filed under: , , , , , ,

In a previous blog post I showed how to use the ReceiveActivity with long running workflow and how to extract the workflow instanceId from the context using the IContextManager. I also showed how to rebuild this context at a later date when you use a new proxy object to call the same workflow instance.

But what happens when there are multiple ReceiveActivity instances waiting for the same request in a workflow. In the workflow below both indicated activities are in a parallel activity so they are waiting at the same time and for the same request.

The way to keep them apart is by specifying the ContextToken for the two ReceiveActivity objects. The picture below shows the ReceiveActivity to the right, the one to the left has a ContextToken named LeftBranch.

Now we know how to keep them apart in the workflow we still need a way to specify this at the clients end. This is done using a conversationId setting on the same context as we specified the instanceId. The only problem here is that this conversationId is a Guid and not something the client can determine by itself so the workflow needs to supply it somehow. For this example I just kept things simple and returned the conversationId from the first ReceiveActivity call. This is the code in the CodeActivity that does just that:

private void codeActivity1_ExecuteCode(object sender, EventArgs e)

{

IDictionary<string, string> context = RightReceiveActivity.Context;

 

string temp;

 

if (context.TryGetValue("conversationId", out temp))

ReturnValue = temp;

}

 

All I need to do is het the Context from the ReceiveActivity I am interested in, the right one in this case, and retrieve the conversationId from it. Remember the context is an IDictionary<string, string> and it will also contain the instanceId for the workflow. In fact I could have just returned this context to the client for future use but as I was using the simple standard interface generated and the client already knew the workflow instanceId I decided to skip this step.

The client code to set the conversationId is simple:

Workflow1Client proxy = new Workflow1Client();

 

IContextManager contextManager = proxy.InnerChannel.GetProperty<IContextManager>();

if (!string.IsNullOrEmpty(_conversationId))

_context.Add("conversationId", _conversationId);

 

contextManager.SetContext(_context);

 

DumpContext(proxy);

 

Console.WriteLine(proxy.GetData(2));

 

Where the _context field points to the context used when creating the workflow and the conversationId is returned from the first GetData() call.

 

Enjoy!

www.TheProblemSolver.nl
http://wiki.WindowsWorkflowFoundation.eu

with 7 comment(s)
Filed under: , , , ,

Sometimes you need to the complete public key of an assembly instead of the public key token. For example when you want to use the InternalsVisibleTo attribute when the target assembly is signed. The easiest way of doing so is using the Strong Name Tool or sn.exe with the –Tp parameter. So from .NET 2.0 command prompt do:

sn -Tp <<your assembly>>

 

And if you want to add an Open .NET 2.0 SDK Command Prompt here shortcut menu option to the Windows Explorer check this tip.

Enjoy!

www.TheProblemSolver.nl
http://wiki.WindowsWorkflowFoundation.eu

with no comments
Filed under: , ,

In my last post I showed how to self host the workflow runtime and still be able to use a Windows Communication Foundation and ReceiveActivity.

Hosting the workflow runtime in a WorkflowServiceHost is nice but in all likelihood you will also need to configure the workflow runtime itself and add some WorkflowRuntimeService to it. So how to do this when you never actually create the workflow runtime yourself?

There are two possible ways to go about this depending if you prefer to use code or a configuration file. Lets first look at the code option as it is easier to see all the working parts. In the case of a WCF hosted workflow runtime the WorkflowRuntimeBehavior is the WCF ServiceBehavior that is actually responsible for creating the WorkflowRuntime. Fortunately getting a reference to it, and thereby the WorkflowRuntime, isn't hard.

// Create the host

WorkflowServiceHost host = new WorkflowServiceHost(typeof(Workflow1));

// Retreive the WF behavior

WorkflowRuntimeBehavior workflowRuntimeBehaviour =

host.Description.Behaviors.Find<WorkflowRuntimeBehavior>();

// Retreive the WF runtime

WorkflowRuntime workflowRuntime = workflowRuntimeBehaviour.WorkflowRuntime;

// Create and add the SqlWorkflowPersistenceService

SqlWorkflowPersistenceService persistenceService =

new SqlWorkflowPersistenceService(connectionString);

workflowRuntime.AddService(persistenceService);

// Start listening

host.Open();

 

Doing the same in a configuration file isn't hard either. The main problem is that a app.config isn't compiled so it's a bit easier to make a typo and not catch it until runtime.

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<system.serviceModel>

<!-- Details ommited -->

<behaviors>

<serviceBehaviors>

<behavior name="WorkflowConsoleApplication1.Workflow1Behavior" >

<!-- Details ommited -->

<workflowRuntime name="WorkflowServiceHostRuntime"

validateOnCreate="true"

enablePerformanceCounters="true">

<services>

<add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

connectionString="Data Source=localhost\sqlexpress;Initial Catalog=WorkflowPersistence;Integrated Security=True;Pooling=False"

LoadIntervalSeconds="1"

UnLoadOnIdle= "true" />

</services>

</workflowRuntime>

</behavior>

</serviceBehaviors>

</behaviors>

</system.serviceModel>

</configuration>

This configuration file is basically the same as in the previous post except that contains a workflowRuntime element inside of the service behavior. This workflowRuntime contains the services collection where you can add any services you need.

 

Enjoy!

www.TheProblemSolver.nl
http://wiki.WindowsWorkflowFoundation.eu

with no comments
Filed under: , , , ,

One of the new, and pretty cool, Windows Workflow Foundation features is the ReceiveActivity that unleashes the power of Windows Communication Foundation to Windows Workflow Foundation. Getting started with a ReceiveActivity is quite simple as long as you start with a sequential Workflow Service Library.

The new service host for Windows Communication Foundation services makes life good as it means you can test a workflow without creating a host application or resorting to IIS.

But sometimes you just want to host the workflow runtime yourself and still use the ReceiveActivity. So how to go about and do that?

For a normal WCF host you would use an instance of ServiceHost but with a ReceiveActivity that isn't quite going to cut it as the host needs some awareness of WF and ServiceHost is very generic. So instead add a reference to System.WorkflowServices and create an instance of WorkflowServiceHost. The syntax is the same so no surprises there:

WorkflowServiceHost host = new WorkflowServiceHost(typeof(Workflow1));
host.Open();
Console.WriteLine("Press enter to stop.");

Console.ReadLine();

 

The app.config contains the runtime configuration but all of it is pretty standard WCF stuff so no surprises:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<system.serviceModel>

<services>

<service name="WorkflowConsoleApplication1.Workflow2" behaviorConfiguration="WorkflowConsoleApplication1.Workflow2Behavior">

<host>

<baseAddresses>

<add baseAddress="http://localhost:8731/Design_Time_Addresses/WorkflowConsoleApplication1/Workflow2/" />

</baseAddresses>

</host>

<endpoint address=""

binding="wsHttpContextBinding"

contract="WorkflowConsoleApplication1.IMyContract">

<identity>

<dns value="localhost"/>

</identity>

</endpoint>

<endpoint address="mex"

binding="mexHttpBinding"

contract="IMetadataExchange" />

</service>

</services>

<behaviors>

<serviceBehaviors>

<behavior name="WorkflowConsoleApplication1.Workflow2Behavior" >

<serviceMetadata httpGetEnabled="true" />

<serviceDebug includeExceptionDetailInFaults="false" />

<serviceCredentials>

<windowsAuthentication

allowAnonymousLogons="false"

includeWindowsGroups="true" />

</serviceCredentials>

</behavior>

</serviceBehaviors>

</behaviors>

</system.serviceModel>

</configuration>

 

Enjoy!

www.TheProblemSolver.nl
http://wiki.WindowsWorkflowFoundation.eu

with 2 comment(s)
Filed under: , , , ,

The first of a two part article I wrote on developing custom workflow activities just appeared on the MSDN Visual Basic Developer Center. You can find the article named "The Power of Custom Workflow Activities" here. A second article with more details is scheduled to appear here as well.

 

For everyone new to Workflow Foundation I would suggest reading some intro level material first. For example my "Workflow Foundation 101" article or "Hello, Workflow" by K. Scott Allen.

Enjoy!

www.TheProblemSolver.nl
http://wiki.WindowsWorkflowFoundation.eu

 

with 3 comment(s)
Filed under: , , , ,

The team building WF is looking for some input on what to do for the future of Workflow Foundation. To find out what you want they created a Windows Workflow and Rules Designer Rehosting Survey. Go ahead and fill it out over here: https://live.datstat.com/MSCSD-Collector/Survey.ashx?Name=WF_Rules_Designer_Rehosting_Blogs

 

Enjoy!

www.TheProblemSolver.nl
http://wiki.WindowsWorkflowFoundation.eu

with 2 comment(s)
Filed under: , , ,

I guess MIX-08 was a pretty cool event Smile Unfortunately all I can do was guess because I wasn't there Sad.

So I guess I missed a lot of good sessions, right? Well wrong actually because the team that run MIX have already put the sessions up on the web! So go to http://sessions.visitmix.com/Default.htm and view all the sessions you want!

I just watched Brad Abrams session about Ajax and VS2008 and its excellent!

And best of all: they are also published in Zune and IPod format so you can take them on the road Smile

Enjoy!

www.TheProblemSolver.nl
http://wiki.WindowsWorkflowFoundation.eu

with 1 comment(s)
Filed under: , , ,

Op 6 maart heb ik een presentatie geven bij de Nationale Office Dag in Ede. Hier zijn de slides en voorbeelden te downloaden.

Enjoy!

www.TheProblemSolver.nl
http://wiki.WindowsWorkflowFoundation.eu

 

with no comments
Filed under: , , ,

Op vrijdag 28 maart organiseert Software Developer Network (SDN) in samenwerking met de .NET gebruikersgroep (dotNed) en VBcentral de community launch van Visual Studio 2008, SQL Server 2008 en Windows Server 2008. Dit evenement loopt parallel aan een reguliere Software Developer Event. Hierdoor zijn de drie Nederlandse gebruikersgroepen in staat om jou een indrukwekkend programma voor te schotelen. Deze dag bestaat uit ruim vijfentwintig sessies, verdeeld over maar liefst zeven paralleltracks. Door het brede aanbod van onderwerpen en de aanwezigheid van veel bekende en gerenommeerde sprekers, mag je dit unieke evenement niet missen!

Alle leden van de drie Nederlandse communities kunnen zich aanmelden en hebben toegang tot alle sessies van die dag. De afsluitende Algemene Ledenvergadering van de SDN is alleen toegankelijk voor SDN leden. SDN leden kunnen zich aanmelden via de gebruikelijke weg en niet SDN leden via de website van Microsoft Nederland. Het evenement vindt plaats in De Reehorst, Ede en de kosten voor niet betalende SDN leden bedragen € 50,00 inclusief BTW.

Bezoek voor meer informatie en het volledige programma de website van de SDN

 

with no comments
Filed under: ,

By default Edit and Continue (EnC) is disabled when you create a new ASP.NET Web Application using Visual Studio 2005. Not sure why this is because EnC is a really nice feature to have and can be a big time saver.

You will notice this when you try to edit the source while debugging and receive the following error message:

Edit and Continue

Changes are not allowed when the debugger has been attached to an already running process or the code being debugged was optimized at build or run time.

Fixing it is easy. Just double click on "My Project", select the Web tab and check the "Enable Edit and Continue" check. Next time when you run you are all set for EnC Smile

 

Enjoy!

www.TheProblemSolver.nl
http://wiki.WindowsWorkflowFoundation.eu

with 5 comment(s)
Filed under: , ,
More Posts Next page »