Welcome

You have reached the blog of Keith Elder. Thank you for visiting! Feel free to click the twitter icon to the right and follow me on twitter.

Part 2: Leveraging Workflow Foundation – Invest in Your Workflow Infrastructure

Posted by Keith Elder | Posted in .Net, Web Services, Workflow Foundation | Posted on 28-05-2007

13

In Part 1 of Leveraging Workflow Foundation we discussed how Workflow Foundation is just an API.  Since APIs don’t provide business value out of the box, it is important engineers exploring Workflow Foundation for the first time approach it in the same manner they would any API: write once, run everywhere.  In other words, instead of building out the workflow components for one application, look at it from the 10,000 feet view.  This is of course going to take more time than one might originally think so be sure to allow for this in development time.  We’ll look at the basics engineers starting with Workflow Foundation will need to think about to invest in their workflow infrastructure.  Who knows, we may even find some rusty washers and shinny pennies along the way.

Think about workflow from a central service for your business not just within one application.  Think about workflow outside of the box.  Think about reusability.  Think about a central rules engine.

While this will not be a comprehensive guide on how to build out one’s infrastructure with Workflow Foundation, I do want to point out several entry points everyone should consider.  The idea is to invest time in Workflow Foundation just as one might in invest other areas of .Net like Asp.Net for example.  I use Asp.Net as an example because most engineers that build Asp.Net web sites have some type of reusable framework they can apply to other web sites they build.  If the same principal is applied to Workflow Foundation and done correctly, it could pay off huge dividends for a business.

The Big Picture From a 10,000 Feet View

We understand we need to invest in our workflow infrastructure.  What are the things we need to spend our time on to make Workflow Foundation more reusable across our teams?  Let’s first look at our goal.  Our goal is to build out a core workflow infrastructure that can be reused among various projects, teams, and applications.  

Now that our goal is set, here are the things we need to focus on to make this a reality:

  1. Provide a central location where workflows can be stored.
  2. Provide a central location where rules can be stored.
  3. Provide a central service where workflows can be invoked.
  4. Provide a central service and API where rulesets can be manipulated and invoked against workflows or instances of any object.
  5. Provide a custom user interface to easily create, modify, update, track and manage existing workflows and rules.  Also this should have the ability to deploy workflows and rules to different environments (test, beta, prod).

As we see there is A LOT that needs to be done to build out a reusable infrastructure.  Let’s start with the first two items above since these are relatively easy to accomplish.   The reason I used the words “easy to accomplish” is because workflows and rules associated with workflows can be expressed in XML.  Once we persist our workflow to XML, which is called XOML, it becomes trivial to store the XOML in a database.  Rules associated with workflows are already created in XML and this makes it easy to store these.  The harder one to deal with is the workflow though.  More on that later. 

When we create our database structures to store workflows and rules XML it is important we do not build our tables in a way where rules are always tied to a workflow.  In other words don’t build a single table.  Workflows and rules should be stored separately and by doing so gives us some nice reusability with the rules engine as we’ll see later on.  Remember we are trying to create not only a reusable workflow infrastructure but a reusable rules engine as well.  Now that we understand workflows and rules can be stored in a database let’s look at how this will be accomplished.

Storing XOML Workflows in the Database

As mentioned earlier we can express our workflows in XML.  At the time of this writing Visual Studio supports two types of workflows.  A code behind workflow and a XOML workflow.  It is the XOML workflow type that we are interested in.  Since the XOML workflow is essentially XML, we can easily store it into a database. 

To persist workflows we need to first create our workflows as XOML based workflows.  With a little bit of code we could persist the XOML into a database.  The next question is how do we instantiate workflows from XOML.   The answer is easy but it is a matter of knowing where to look.  To create an instance of a XOML workflow we have to dig a little deeper into the APIs but not too far.  The method we are going to look at is CreateWorkflow().  CreateWorkflow() has six overrides and it is the sixth override that provides us the entry point we need not only for workflows but also to pass in rules our workflow would use.  Here is the syntax of it:

public WorkflowInstance CreateWorkflow (

                XmlReader workflowDefinitionReader,

                XmlReader rulesReader,

                Dictionary<string,Object> namedArgumentValues

            )

 

The reason this override method in particular is interesting is it allows us to pass in all the arguments we need to kickoff our workflow including our XOML, our rules and any parameters the workflow needs. 

When you first add a workflow object to your solution, but sure to select the one that is XOML based, here is a screen shot from Visual Studio.

Assuming an interface is built to manipulate workflows outside of Visual Studio, using the XOML based workflow will allow us to adjust the workflows in real time without having to recompile assemblies and redeploy them (assuming the code behind doesn’t need modified).  Be sure to download the workflow samples available as it contains examples of how to rune workflows with XOML.   The main thing missing from Visual Studio though are tools to assist in running and deploying XOML based workflow definitions so plan on devoting a lot of time to this area as the documentation and tools available are slim.  Keep your eye on the prize though! 

Just for the record, here is a sample hello world XOML workflow to give you an idea what the XOML looks like:

<SequentialWorkflowActivity x:Class=WorkflowLibrary1.Workflow2 x:Name=Workflow2 xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml xmlns=http://schemas.microsoft.com/winfx/2006/xaml/workflow>

    <CodeActivity x:Name=codeActivity1 ExecuteCode=codeActivity1_ExecuteCode />

    <CodeActivity x:Name=codeActivity2 ExecuteCode=codeActivity2_ExecuteCode />

</SequentialWorkflowActivity>

 

The first code activity prints “Hello” and the second prints “World”.  Since we’ve expressed this in XML we could easily manipulate the workflow to print “World” then “Hello” simply by moving the codeActivity2 above codeActivity1.  We could do this without needing to redeploy any code.

The hard part of this is tying the ability to persist XOML workflows with the big picture item number five.  Storing our XOML in a database doesn’t necessarily make us agile from a business standpoint, it is the interface the end users (business analyst or other engineers) interact with and the central workflow services we expose that is going to make us more agile.  This is where the majority of your time is going to be spent.  There is good news in that there are numerous samples floating around on the Internet to give you a better idea.  Be sure to checkout the samples here.  You are also going to have to devote a fair amount of time to the ComponentModel to create the desired UI experience to load a workflow from XOML, alter it, and then persist it back. 

As we discussed in part 1 there are rusty washers and this is one of them.  While we can off load workflows to the database we will find there aren’t many tools to assist us in doing so and the art of doing this will seem kludgy and an after thought at best.  I personally spent several hours trying to get workflows to reliably load from the file system and couldn’t.   I’m sure it was something simple I wasn’t doing but the whole process was very inelegant.  Hopefully the Workflow Team will beef up their tool offerings in the next version of Visual Studio to make this more trivial.  Because of the lack of time to devote to this our team decided we would revisit it at a later date when we had more time.

 

Storing Workflow Rules in the Database

We’ve looked at storing workflows so let’s move onto storing rules in the database.  The rules engine aspect of Workflow Foundation turned out to be a shiny penny and one that isn’t talked about much.  #2 and #4 of our big picture items is off loading rules to the database and then creating a central service where rules can be invoked. 

When we add a “policy” activity to a workflow we can associate one or more rules to it.  Once a rule is defined we can also re-use it within the workflow.  That’s great, but what if we want to reuse the same rules again in a different workflow?  This is one reason why we want to off load these rules into a separate location.  When rules are created within Visual Studio by default they are stored in a hidden file called .rules.   The nice thing about the rules is they are already written in XML. Here is a screen shot so you can see how this appears from Visual Studio.

 

This is also where the second parameter of CreateWorkflow() override number six comes into play.  We can easily offload the rules we’ve created into another database table or set of tables and then pass those into the workflow at runtime.  Not only can we leverage the built in rule APIs within Workflow Foundation for workflows we can also utilize this for validating instances of objects that could then be used across multiple applications.   During my exploration, once this light bulb went on I realized that I could really save my team a lot of time.  I started down the path of building out a tool that could not only serve the purpose of storing rules for workflows but also a tool that could be called via a service from any application.  I call the tool “Orbb”.

Orbb – Object Rules Business Builder

According to our goals as outlined above, we knew we wanted to store rules in a database and then expose functionality via a service.  To make ourselves more agile we need an interface to manipulate these rules.  During my exploration of the rules engine that ships with Workflow Foundation it became apparent that rules can be run against ANY INSTANCE OF ANY OBJECT.  This is powerful because it means we aren’t tied to XML like Biztalk for example.  For example we could have a Winform instance that needs to have rules performed against it, or maybe an Asp.Net web page, or may a simple business entity like a purchase order.  As long as it is an “instance” we can leverage the rules engine that ships with Workflow Foundation.

Once this light bulb went off, a few hours later I had a database, WCF service and a user interface to build, manage and centrally store rules for a variety of applications.  Orbb was then born.  Today Orbb is just a proof of concept but the value it could provide is unquestionable.   It is in a very infant stage right now and may never see the light of day but it is far enough along I can share a screen shot with you here.  Here is a screen shot:

The idea is fairly simple.  An application is created within Orbb and then permissions are setup (who can edit / change rules for each application) along with the various environments you need to test your rules (test, beta, prod).  Those that are granted access can then use Orbb to manage not just one application but multiple applications.  Imagine one central service where rules could be stored, validated and retrieved. 

For example, imagine you have a smart client where users can create a new helpdesk ticket.  The business informs you that users aren’t entering enough information in the “what is wrong” textbox and they want you to force them to enter at least 150 characters.  Instead of having to add this rule to your code by hand and re-push it, you could simply launch Orbb, select the form and add the new rule to the form.  Then copy the new ruleset to your test, beta and prod environments without having to redeploy your application. 

This type of flexibility could also be applied to workflows whereby rules change.  Being able to adjust your workflow rules without having to redeploy is definitely worth an investment.   One of the things that came out of Orbb as I worked through it was a generic class that takes any Object and retrieves the rules from a database and then validates the object using the rules.  You could utilize this in a service, Winforms, Asp.Net pages, business objects and more.  I have provided a copy of this below in the “Validating Any Object with Workflow Rules Engine” section.

Conclusion

As you can see there is quite a bit of work that can be done to leverage Workflow Foundation and your mileage will vary in regards to your time / benefit ratio.  In the end it will pay in huge dividends if an investment is done up front, not as an after thought.  In part 3 of Leveraging Workflow Foundation we’ll look at hosting the workflow runtime.  Will we find any rusty washers?  Stay tuned!

Validating Any Object With Workflow Rules Engine

using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.Practices.EnterpriseLibrary.Data;

using System.Data.Common;

using System.IO;

using System.Xml;

using System.Workflow.Activities.Rules;

using System.Workflow.ComponentModel.Serialization;

using System.Workflow.ComponentModel.Compiler;

 

namespace Orbb.BusinesLayer

{

    /// <summary>

    /// This is a generic class that will take any object and process rules

    /// against that object that are defined in a database.

    /// </summary>

    public class ObjectValidation

    {

        private object entity;

 

        /// <summary>

        /// The object that needs to be validated.

        /// </summary>

        public object Entity

        {

            get { return entity; }

            set { entity = value; }

        }

 

        private string ruleSetName;

 

        /// <summary>

        /// Name of the RuleSet that is in the database we need

        /// to use.

        /// </summary>

        public string RuleSetName

        {

            get { return ruleSetName; }

            set { ruleSetName = value; }

        }

 

        private System.Workflow.Activities.Rules.RuleSet ruleSet;

 

        /// <summary>

        /// Deserialized RuleSet object which contains all the rules.

        /// </summary>

        public System.Workflow.Activities.Rules.RuleSet RuleSet

        {

            get { return ruleSet; }

            set { ruleSet = value; }

        }

 

        private RuleValidation ruleValidation;

 

        public RuleValidation RuleValidation

        {

            get { return ruleValidation; }

            set { ruleValidation = value; }

        }

 

 

        private WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();

        /// <summary>

        /// Provides the extensible Application Markup Language (XAML) serialization services

        /// to workflow at design time.

        /// </summary>

        public WorkflowMarkupSerializer Serializer

        {

            get { return serializer; }

            set { serializer = value; }

        }

 

        private System.Workflow.Activities.Rules.RuleExecution ruleExecution;

        /// <summary>

        /// Stores state information while executing RuleCondition or RuleAction classes.

        /// </summary>

        public System.Workflow.Activities.Rules.RuleExecution RuleExecution

        {

            get { return ruleExecution; }

            set { ruleExecution = value; }

        }

 

        public ObjectValidation(Object entity, string ruleSetName)

        {

            this.Entity = entity;

            this.RuleSetName = ruleSetName;

 

            // Get the rule from the database

            this.GetRuleFromDatabase();

        }

 

        /// <summary>

        /// Gets the rule from the database as specified.

        /// </summary>

        private void GetRuleFromDatabase()

        {

            Database db = DatabaseFactory.CreateDatabase(“OrbbConnectionString”);

            using (DbCommand cmd = db.GetSqlStringCommand(“select RuleSet from Rules where Name=@Name”))

            {

                db.AddInParameter(cmd, “Name”, System.Data.DbType.String, this.RuleSetName);

                string ruleSet = (string)db.ExecuteScalar(cmd);

                this.DeserializeRuleSet(ruleSet);

            }

            this.ValidateRuleSet();

        }

 

        /// <summary>

        /// Deserializes a ruleset from the database into a RuleSet object.

        /// </summary>

        /// <param name=”ruleSetXmlDefinition”></param>

        private void DeserializeRuleSet(string ruleSetXmlDefinition)

        {

            if (!String.IsNullOrEmpty(ruleSetXmlDefinition))

            {

                StringReader stringReader = new StringReader(ruleSetXmlDefinition);

                XmlTextReader reader = new XmlTextReader(stringReader);

                this.RuleSet = Serializer.Deserialize(reader) as RuleSet;

            }

        }

 

        /// <summary>

        /// Executes the rule set on the given entity.

        /// </summary>

        public bool ExecuteRule()

        {

            if (null != ruleExecution)

            {

                try

                {

                    ruleSet.Execute(ruleExecution);

                }

                catch

                {

                    throw;

                }

                return true;

            }

            else

            {

                return false;

            }

        }

 

        /// <summary>

        /// Validates that the entity being processed contains the properties

        /// defined in the ruleset.

        /// </summary>

        private void ValidateRuleSet()

        {

            ruleValidation = new RuleValidation(this.entity.GetType(), null);

            if ((null != ruleValidation) && (!ruleSet.Validate(ruleValidation)))

            {

                string errors = “”;

                foreach (ValidationError validationError in ruleValidation.Errors)

                {

                    errors = errors + validationError.ErrorText + “\n”;

                }

                throw new Exception(errors);

            }

            else

            {

                ruleExecution = new RuleExecution(ruleValidation, this.entity);

            }

        }

 

    }

}

 

 

Like this article? kick it on DotNetKicks.com

Part 1: Leveraging Workflow Foundation – It is just an API

Posted by Keith Elder | Posted in .Net, Asp.Net, Web Services, Workflow Foundation | Posted on 12-05-2007

1

A few weeks ago we launched a new feature for one of our internal applications that leveraged Workflow Foundation extensively.  When working through a new technology you will always find curve balls along the way.  I like to call these shiny pennies and rusty washers.  For example, something may seem like a shiny penny when you first see it in a demo.   After much consideration of weighing the features vs the learning curve of the new technology you decide to use it a production environment.   Once something goes into production the game changes.  This is the point where you are going to be held accountable by the business or your client for the technology you chose to use.   This is the point where you have to go deep with the new technology because you have to support it once the “copy to production” button is pressed.  It is during this phase you find some of those shiny pennies are actually rusty washers. 

You will always find rusty washers when you work through a new technology.  There are even some recent examples of this I ran across in blog posts.  For example Jeff Barnes has a blog post about how WCF proxies can only fault once. If you’ve done ASMX proxies you know we don’t have to deal with this.  With WCF apparently the game has changed.  It is an example of a rusty washer with WCF that you wouldn’t know until you tried to put it into production.  Another example of recent that comes to mind is Ayende’s post about NHibernate one-to-one mappings.  Again, another example of something you wouldn’t find out when watching a demo.

To help you limit the amount of rusty washers you will run into with Workflow Foundation, I wanted to share our team’s experience in working through Workflow.  In this multiple part series we’ll look at some of the challenges the team faced and how we solved some of these.  I say “some” of these because we took side steps around the rusty washers we found due to our short time frame.   Hopefully this brain dump of information will save others time who are about to start using Workflow Foundation.  I’ll cover some of the in and outs where you will want to look into workflow and some of the pitfalls we had to work around (the rusty washers). 

First let me say that all in all we are extremely happy with the end product after launch.  We are going to be able to easily modify business rules and adjust quickly for the business.  As a matter of fact we have already had to modify our business rules and add new features.   Our end goal for selecting workflow foundation for this particular project was future agility.  Using Workflow allowed us to hit this mark, but not in the way we originally intended.  If we would have had more time we could have worked through the rusty washers and turned them into shiny pennies.  This brings me to my first point of this series.

It is just an API

The first thing I think everyone needs to understand about Workflow Foundation is it is just an API.  Or to borrow the word from its own name, a foundation to build upon.  It is really no different than building a house whereby you first pour the foundation and then you build something on top of it.    A lot of experienced .Net developers (including myself) think of Workflow Foundation as more of an extension to the core .Net 2.0 framework although it was released with .Net 3.0.  Technically this is true since .Net 3.0 is just that, an extension to the .Net 2.0 framework release whereby WPF, WCF, and WF were added. 

The reason I point out that WF is just an API is to set the initial expectation.  A lot of people I’ve come in contact with seem to think Workflow Foundation is in fact a shiny penny that will magically solve all of their problems.  I’ve heard them say, yeah it is cool, you just drag and drop and you’ve got workflow.  This is where I have to jump in.  The reality is it a core framework for building workflows and Microsoft provides several key components with the workflow framework.   Out of the box you get a:

  1. Runtime – the brain of the workflow engine that is constantly running in memory and processing workflows
  2. Component model – the pretty user interface that let’s you build workflows within applications or visual studio
  3. Rules engine – well, it really isn’t an engine (it is just an API) but a processing mechanism to process business rules against workflows or use as a stand alone rules processor
  4. Services – they provide various things such as how workflows should be processed (manual or default) and also things like persistence and tracking.   Services allow you to customize and tweak how Workflow Foundation works.  Example, if you don’t like the built-in persistence table structure you can create your own service and persistence store.

As you can see you get a lot out of the box.  All for the low low price of $0.00.  Not a bad investment huh? 

Question:  What do I do with all this?
Answer:  Anything you want that fits this tools job description.

The point I am trying to make here is Workflow Foundation provides a base model to build anything on top of it.  Take Winforms for example.  Microsoft didn’t ship a collection of pre-built out of the box applications.  Instead they provided the base framework so you, the developer, can build any type of Winform application you need.  Please don’t think of Workflow Foundation in any other way.    In other words, leveraging Workflow Foundation should be treated like an infrastructure investment, not an application investment.   In part two we’ll cover some of the key points you should focus on when building out your workflow infrastructure.  See you in part two!

It is easier to modify a workflow than it is to modify thousands of lines of C# code.

Like this post?  kick it on DotNetKicks.com

ASP.NET Web Services and WCF Very Different Animals

Posted by Keith Elder | Posted in .Net, Asp.Net, Web Services | Posted on 27-02-2007

7

For the past several days I’ve spent a lot of time trying to get up to speed using Windows Communication Foundation.  I’ve seen or watched enough “Hello World” demos of WCF over the past year to choke a good mule to death but I haven’t had a chance to write anything using WCF for real world experience.  I knew I’d get around to it eventually.  This is the point where you actually learn how to use a technology anyway.  Having done large scale applications with Asp.Net web services for quiet sometime I honestly didn’t figure it would be that difficult.   I was wrong.  My first real world venture into WCF left me scratching my head and feeling like a 12 year again. 

My reason for using WCF is I’m staring a new project which will be a Smart Client application used to build and manage business rules for different .Net applications leveraging the Windows Workflow Foundation rules API.  Since I was leveraging the .Net 3.0 framework anyway, I thought now was as good a time as any to jump into WCF. 

Once I defined my database structure and calculated which web service methods I was going to need, I created my ISomethingInterface contract which defined my methods.  I then implemented those methods in my service.  Very simple stuff at first, then I pressed F5 in Visual Studio and I was greeted with errors because my web.config file wasn’t configured.

I knew I had to configure the service and so off I went researching how to write the web.config file to expose my service.  I went to MSDN only to learn that I was going to spend the next several hours reading all of these different configuration options (WCF is flexible, but with flexibility comes more to read).  I gave it a college try trying to configure the web.config by hand and then eventually got frustrated because it wasn’t working.  Finally after doing some other searches I see a screen shot of a new item menu in the context menu when you right click the web.config file called “Edit WCF Configuration”.  I click it and get this:

If I’d only know this was there earlier.   After I got my service configured so it gave me a result other than an error page I *thought* I was going to get the same type of page you get with normal Asp.Net web services which is a page that shows you the methods available.  I was wrong.  I got this:

Where’s my list of web methods!?  Not there.  Again different from what I was expecting.  By this point I had resigned myself to throwing everything I knew about ASP.NET Web Services out the window because obviously previous knowledge was not really helping. 

I decided to absorb my new service in my client.  Since I had gotten burned by the right mouse click thing earlier I decided to see if the WCF CTP put a menu item in my project so I could generate the class file with svcutil.exe instead of wsdl.exe. Sure enough it was there.  This was the only thing that left me warm and fuzzy, something I had done before.   I then wrote a quick line to leverage the service (which I had placed in a separate Class Project) and it didn’t work.   The app.config file generated was placed in the project file where the service was generated, but not in the project the application was going to run from.   Luckily I was smart enough to just copy the one created for me and it worked.  Again, different. 

Feeling I had made progress I made the methods I wrote work, wrote unit tests for them and then baked them into the user interface of the application.  Then it hit me that I needed to call these services asynchronously.  So I typed “service.” and waited for intelilsense to see what the async calls were named.  They weren’t there!  Uh oh.

Doing some more digging I learned the svcutil.exe has a switch to generate asynchronous calls. The switch is /async.  Reading further there are different types of async calls and this is where I am currently at, trying to figure out what I really need to do and all the ins and outs of async calls in WCF.  Obviously lots of differences as I move further into WCF.

I did find a really good article which tells the developer what the differences between the two are, you may save yourself some headaches.  There are also some other documents nearby this one in the menu on MSDN that you may want to read as well.