views:

334

answers:

2

I have a client who's interested in utilizing Windows Workflow technology in a web-driven application. I'm a .Net developer but have no experience with either WF or SharePoint workflows. Most of what the client wants to do seems to be straight-forward except that they want the ability for end users to be able to create/edit their own custom workflows. In my brief research into WF, it doesn't seem like this is how things are done typically. Is it feasible to allow users to create workflows themselves, or should this really be a custom ASP.Net MVC app, or maybe a SharePoint app?

Thanks for your input!

Andy

+4  A: 

Having users be able to change workflows is supposed to be one of the stron points of WF. However with WF 3 the whole model is geared very much to code generation and not markup so it is hard to do. Not impossible as you can use pure markup workflows but it is hard.

With WF 4 the story is supposed to be much better as all workflows are pure markup and there is no code involved at all. All code is in predefined activities, which are compiled, and the user can change the workflows as needed. Also the WF designer is much easier to rehost in your own application.

PS SharePoint workflows are WF 3 workflows, even in the new SharePoint version, and WF 4 is a completely new product that shares no code whatsoever.

Maurice
A: 

You may want to bulid a state machine that can accept triggers from the users. Nicholas Blumhardt has a really great, lightweight state machine implementation called stateless. You can create a state machine with a simple statement:

var stateMachine = new StateMachine<TState, TTrigger>();

From the project site:

var phoneCall = new StateMachine<State, Trigger>(State.OffHook);

phoneCall.Configure(State.OffHook)
    .Permit(Trigger.CallDialed, State.Ringing);

phoneCall.Configure(State.Ringing)
    .Permit(Trigger.HungUp, State.OffHook)
    .Permit(Trigger.CallConnected, State.Connected);

phoneCall.Configure(State.Connected)
    .OnEntry(() => StartCallTimer())
    .OnExit(() => StopCallTimer())
    .Permit(Trigger.LeftMessage, State.OffHook)
    .Permit(Trigger.HungUp, State.OffHook)
    .Permit(Trigger.PlacedOnHold, State.OnHold);

// ...

phoneCall.Fire(Trigger.CallDialled);
Assert.AreEqual(State.Ringing, phoneCall.State);

As you can see the code is pretty straight forward. You can accomplish all that you need with a single project.

Since the State and Trigger can be of any type, you can feed the state machine from a database, maybe a Step table, and allow for the triggers of Approve=1, Reject=2. You could create a series of steps ahead of time with the users and allow them to select the triggers by presenting with a step, then allowing them to assign the next step based on the trigger they pick.

David Robbins