October 2006 - Posts

By default the web service wrapper generated around a workflow use the "tempuri.org" namespace. Not very pretty and certainly not something you want to use in a deployed application. So people started complaining and Microsoft listens (sort of).
 
Paul Andrew published the solution on this blog at http://blogs.msdn.com/pandrew/archive/2006/10/25/extending-the-wf-publish-as-web-service-or-get-rid-of-tempura-org.aspx. Now I don’t like it as it means searching for temp files with vague names, copying them and changing the generated code and ASMX page. Not exactly a pretty solution by any standards.
 
Unfortunately this is all we are going to get for now. Lets just hope a service pack to address this behavior doesn't take too long (yea right).
 
And while I am going on about it, how come there is only an ASMX web servide wrapper and no WCF wrapper? Really sounds like that is what we are supposed to have in the first place.
 
with 1 comment(s)
Filed under: , ,
How often can you meet a software legend in the Netherlands? Not very often, I tried to get him to the Netherlands earlier this year for an SDE event but unfortunately scheduling conflicts prevented this :-(
 
Well VBCentral and André Obelink has been more successful and will host an event with Jackie as speaker on November 22nd. You can register for this event at http://www.vbcentral.nl/tabid/166/Default.aspx.

Highly recommended!
 
Its almost time, less than two weeks to go to the start of Tech-Ed Developers in Barcelona. I am really looking forward to it :-) Just hope my back isn't going to trouble me too much as recovery is going a bit slower than I originally expected :-(
 
If you are going come by an the Ask The Experts stand and say hello or ask any question you might have about Windows Workflow, LINQ, VSTO or .NET 3.0 in general.
 
See you there :-)
 
with no comments
Filed under: , , , ,
So you are going to add WF to your application, great but now you are faced with some decisions like:
  • Use state versus sequential workflows.
  • How much to put in a single workflow.
  • Where to leave all the information used by the workflow.
 
Well a while ago I wrote a blog entry on the choice of state versus workflows, see http://msmvps.com/blogs/theproblemsolver/archive/2006/10/11/Sequential-versus-State-workflows.aspx for the details. Next time I will write about where to leave all the information/data required by the workflow.
 
So the next question is how much to put in a single workflow. This is basically a question of creating bit catch all workflows versus smaller granular workflows.
 
My take on this is to create uses cases and turn each use case into a workflow. So let’s look at an example. A customer goes to a online shop, picks a few items, orders them and ask form them to be shipped. This is the basic use case but we can think of a number of additional use cases that may apply. For example:
  • The customer might prefer to pick the goods up in person instead of having them shipped.
  • The customer returns some of the goods as defective.
  • The customer returns some of the goods as unwanted. In the Netherlands this could easily happen because a consumer is permitted by law to return any item within 7 days of the purchase in which case he or she should get a complete refund.
  • A customer might not pay the bill and legal action should be started.
  • Etc…
 
Now all of these actions are valid variations of the basic sale but would it be smart to design them all into the same workflow? No certainly not! The workflow would become excessively large and complex with lots of actions that never execute during normal operations.
 
So I suggest you create a basic workflow consisting of a normal sales action. This consists of:
  1. Pick items.
  2. Choose delivery method.
  3. Choose a payment method.
  4. Spawn a new delivery workflow depending on the delivery method.
  5. Spawn a new payment workflow depending on the payment method.
  6. Wait for the delivery workflow to notify the sales workflow that the delivery is made or canceled.
  7. Wait for the payment workflow to notify the sales workflow that the payment is finished.
 
Now the payment and delivery are separated out of the main workflow. This way it becomes easier to support alternatives or reuse them in other places. For example if the customer returns a defective item we will have to ship him a new one. Shipping is no different but the whole process of handling defects is vastly different from selling the original item.
 
An alternative to spawning new workflows would be to modify the workflow at runtime adding the required steps. The main benefit would be that everything stays nice and contained in a single workflow making it easier to track but the drawback is that part of the workflow is designed in code removing the a major benefit of WF in that a picture is worth a thousand words.
 
Conclusion
Model your workflows after the real processes in your organization. If one process activates another take a good look if it is really part of the first process of more the result of it. Often it will turn out to be just a new resultant process that really should be a different depended workflow.
 
 
with no comments
Filed under: , ,
Google has only just released its possibility to create a custom search engine and already people are putting it to good use.
 
Dan Appleman decided to create a search site targeted at .NET developers. Now I have always said that Google is my friend when it comes to finding information but sometimes it just servers up a bit to much for my own good. Well Dan's site will be a welcome first filter, only searching through selected sites and thus filtering out a lot of the garbage.
 
See his announcement at http://www.danappleman.com/?p=49 or the search engine at http://www.searchdotnet.com/
 
I already bookmarked the search page :-)
 
Enjoy!
 
with no comments
Filed under:
Brian Jones has released a few videos about working with the new XML based document structure in Office 2007. They make for some interesting watching if you are new to the Office 2007 XML format.
 
 
Using the content controls in Word 2007:
Recommended!
 
with no comments
Filed under: , ,
I just found two interesting blog post about dynamically updating workflows by Bart de Smet.
 
WF - How to make a workflow dynamic?
 
Recommended!
 
Maurice de Beijer
 
with no comments
Filed under: , ,
I recently gave Microsoft Expression Web a spin while working on a new web site. I must say I was pleasantly surprised. Now I didn't do a full test of review but did use it to create a template for the new web site using the build in templates as start. Renaming a few files and a few small tweakes where enough to have it working in VS2005 as a regular ASP.NET web site.
 
One thing I noticed was that quite a few features where very Frontpage like. Well I guess that should not be a surprise :-)
 
Certainly a product to keep an eye on.
Maurice de Beijer
 
with no comments
Filed under: ,
For example adding child Activities to a another.
A WhileActivity can only contain a single child activity, the same is true for a ReplicatorActivity. However a IfElseActivity and a ListenActivity can contain multiple child activities. Now the difference doesn't matter much as the single activity in the WhileActivity or ReplicatorActivity can be a SequenceActivity which in turn can contain multiple children but still it's confusing.
 
When a ConditionedActivityGroup is used you drop whatever activities you want in and these activities gain an extra property, the WhenCondition. On the other hand with the FaultHandlers you drop a FaultHandlerActivity in the top, set its FaultType and drop the activities you want to execute below. By the way the same difference as above applies, the ConditionedActivityGroup accepts a single child activity for each branch while the FaultHandlers accept multiple children for every FaultHandlerActivity.
 
Now this isn't much of a problem but the behavior seems inconsistent. If there is some good reason I am missing I would appreciate the info.
 
Enjoy!
 
Maurice de Beijer
 
with 2 comment(s)
Filed under: , ,
Scott Guthrie just posted the news that ASP.NET AJAX Beta 1 is released. No not the final product but Beta 1! It is kind of hard to believe that the product is just at the Beta 1 stage. After all it has been talked about so much that it almost sounds like its been around for years and version 5 is about to be released. But no it is all hype so far. But that said I think it’s a very exciting product that will help ASP.NET developers create much more dynamic sites. But like anything else out there with a lot of power it also opens the door to a lot of misuse, lets hope this doesn’t happen to much and give a very useful product a bad name.
 
 
Enjoy!
 
Maurice de Beijer
 
with no comments
Filed under: ,
The PolicyActivity is rather cool but with more than a few rules in the RuleSet and full chaining enabled it can become a bit hard to see what is going on. Now it would be nice if we could step through the rules with the debugger but if there is a way I haven't found it yet. Of course you could add Console.WriteLine statements to the actions, after all they can be multiple statements. There is however an easier way that will show exactly what the runtime engine is doing and that is tracing.
 
Add the following to the app.config:
  <system.diagnostics>
    <switches>
      <add name="System.Workflow.Activities.Rules" value="Verbose" />
    </switches>
  </system.diagnostics>
And run the workflow again. This time the Immediate Window will contain a trace with all rules being loaded and their dependencies. After that the trace will contain all evaluations of conditions and results thereof. The following is an example of a small RuleSet I created:
 
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "+5%" Condition dependency: "this/amount/"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "+5%" THEN side-effect: "this/rate/"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "10%" Condition dependency: "this/age/"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "10%" THEN side-effect: "this/rate/"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "50%" Condition dependency: "this/age/"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "50%" THEN side-effect: "this/rate/"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "Calc" Condition dependency: "this/"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "Calc" Condition dependency: "this/amount/"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "Calc" Condition dependency: "this/rate/"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "Calc" Condition dependency: "this/discount/"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "Calc" THEN side-effect: "this/discount/"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "+5%" THEN actions trigger rule "Calc"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "10%" THEN actions trigger rule "Calc"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "50%" THEN actions trigger rule "Calc"
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "Calc" THEN actions trigger rule "Calc"
System.Workflow.Activities.Rules Information: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Executing
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Evaluating condition on rule "+5%".
System.Workflow.Activities.Rules Information: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "+5%" condition evaluated to True.
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Evaluating THEN actions for rule "+5%".
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Evaluating condition on rule "10%".
System.Workflow.Activities.Rules Information: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "10%" condition evaluated to True.
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Evaluating THEN actions for rule "10%".
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Evaluating condition on rule "50%".
System.Workflow.Activities.Rules Information: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "50%" condition evaluated to True.
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Evaluating THEN actions for rule "50%".
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Evaluating condition on rule "Calc".
System.Workflow.Activities.Rules Information: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "Calc" condition evaluated to True.
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Evaluating THEN actions for rule "Calc".
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "Calc" side effects enable rule "Calc" reevaluation.
System.Workflow.Activities.Rules Verbose: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Evaluating condition on rule "Calc".
System.Workflow.Activities.Rules Information: 0 : Rule Set "Rule Set1": InstanceId 4c453688-cb02-41e9-a641-39921711d2a0: Rule "Calc" condition evaluated to False.

Rather nice as you can see exactly what is going on. Just make sure you name your rules well otherwise it will still be somewhat hard to follow.
Enjoy!
Maurice de Beijer
 
with no comments
Filed under: , ,
Some time ago I installed the Google Desktop Search utility so I could quickly search my hard drive for all sorts of stuff I know is on there but can’t remember where. Well some time ago I discovered that hitting Windows+G was a fast way of searching my desktop as it started a new browser window and brought me to the Google Desktop search window.
 
Well this morning I hit the Ctrl key twice by accident and discovered that was an even faster way to search :-) Doing so activates a small popup window allowing you to search the local disk and the Internet. It even lets you start programs, just hit Ctrl twice and type notepad and start it, next time just typing an N is enough to have it at the top of the list. Now I have no clue how log I have had this feature but it sure is useful :-)
 
Enjoy!
 
Maurice de Beijer
 
More Posts Next page »