During both my presentations this last week on the Windows Workflow Rules Engine I had a lot of good questions. A few of them I was unable to answer on the spot and I indicated I would post the answers here on my blog. Well, as I mentioned in an earlier post, I forgot what one of them was (if someone remembers, please let me know). Also, one question that was asked I answered, but I’m not sure I got it right so I cover that one here too.
First off, Jim Holmes from the Dayton group asked if there was a way to iterate through all the workflows that were currently persisted to a persistence store. I was describing the capability of WF that allows for idle workflows to be persisted out to a persistence store, which is handled by the workflow persistence services. I mentioned that you needed to hold on to the workflow instanceID because that was the way you could reach back into the system to get a reference to a workflow if you needed to cancel it, send it events or maybe even change it with Dynamic update.
A scenario was put forth as follows: “You have 1,000 workflow instances in your system and you need to perform a dynamic update on them. Since these would most likely all be in the persistence store, is there a way to iterate them without having their InstanceID?” My initial response was that I do not believe there was a way of doing that and that you would need to have kept the instance IDs and pull the one at a time. I want to step back and say it looks I was correct, and incorrect.
I was unable to find anything on the abstract WindowsPersistenceService (which a persistence service must inherit from) class that would allow me to get a set of workflows from the persistence store. However, on the out of the box SqlWorkflowPersistenceService there is a method named (innocently) GetAllWorkflows, which does indeed bring you back a full list of all persisted workflows in the form of an IEnumerable set. One of the members of SqlPersistenceWorkflowInstanceDescription is WorkflowInstanceId. So, the real answer to Jim is really, it depends on the persistence service you use. The out of the box SQL version will be able to do that for you, while others may not have that capability. If you are rolling your own persistence service, you’ll need to think if you need this capability or not.
The second question I want to touch on I believe came from Monish Nagisetty from Quick Solutions at the Columbus group. I had an answer for this question, but I wanted to follow up on it anyway. The rules engine has to operate against a specific type. Usually this type is the workflow, but if you use the rules engine outside of workflow it will require you to indicate a Type that the rules will be applied against. For example, in my demos I used an Order object that the rules were evaluating against, so the Order type would be what I passed into the RuleValidation object.
Monish’s question was, “Can I use a list?". My answer was yes, you could use a list. After all, the code just wanted a valid Type. I did mention that I recommended that you construct a class type and then put the lists you wanted to in there, and after some investigation I now know why. As it turns out as I attempted to pull this off in a small spike it’s a little more convoluted than one would hope.
First off, the type the rules are related to is NOT stored in the .rules file. At first I was surprised by that but then thinking about the fact that I had to indicate the type when I created the RuleValidation object it made sense. In the end, as long as the type has the properties and methods the rules indicate it will operate on the rules will be valid and can execute. This is good to keep in mind.
So I started to try to set up a set of rules based on List. This proved to be more painful than it should be (I gave up trying to get valid rules created that accessed the orders I wanted to access given that List doesn’t have an Items property and attempting to do this in the rule would not validate). I even started playing with the codedom xml rules file by hand, which was of course, (in the words of my two year old) yucky. In the end it was much simpler to create a class called OrderList that had a property of type List and pass that in instead. So, I’m going to say that while you CAN pass any type into the rules engine it is probably better to stick with a type that has a set as a property if you need it rather than attempting to pass the set itself.
Please let me know if these help clarify my explanations or not. If I said anything in the presentations that was just downright incorrect, please feel free to let me know. I’d rather people know how it really is. Also, if someone does remember what that other question was, please contact me.