I have been tasked with creating a web application which will provide end-users with a self help workflow, asking them questions and skipping to another part of the workflow depending upon the responses until they reach the end.

This is fine, and I was considering creating a data driven application which administrators could create and save new workflows themselves. This would be based upon the following DB tables:

  • Categories
  • Workflows
  • Steps
  • Responses

However, I have now been told that these workflows would contain some automated check steps, such as checking a value in a DB somewhere, or a reg key value on the users workstation, or an LDAP value from Active Directory (ad inifinitum) against a known/desired value (which itself would be dynamic in some cases). This completely throws a spanner in the works as now it looks like I'm going to have to hard code all of the workflows into the application, which I was hoping to avoid.

Is there a way that I could approach this that I'm not seeing that will allow me to continue to make the application (somewhat) data driven? Or is it OK/standard to hard code these types of workflows into an app? The customer will be wanting to add new workflows regularly I am told.

For info, I will developing this in C# as we are a MS shop.


I can think of two possible solutions here, but they both require a fair amount of development (but I really can't see a solution where this is not the case). I would also recommend not developing any specific kind of check step until it is actually needed. It's very easy to have requirements for 42 different kinds of automated steps that end up having only two or three of them actually used.

Option 1: Hard-code the Steps

You don't have to hard-code the workflows, but you have to hard-code the automated check steps. I'm assuming that your basic structure would have a Step with multiple Responses and each response sends the person filling out the questionnaire to a new Step right? In that case, you would create different types of Steps.

  • The basic step would be a 'QuestionStep' that simply has a list of possible Responses the user can define and add himself, with the associated step to jump to
  • Another step would be the 'DatabaseValueStep' that would allow the user to input a query to be executed and define a list of values that can be returned, with the associated step to jump to.
  • Another step would be the 'LDAPValueStep' that allows the user to input the AD-property to check and define a list of values that can be returned, with the associated step to jump to.
  • ...

Each kind of automated check step requires development.

Option 2: Push data into a table in your application and check that

You could define a dynamic system of keys and values that are imported into a database. The keys are dynamic and can be added into the database, after which they become available in your application in a CheckStep. You have to create integrations between other systems and this system to get your data, but it offloads the work from your workflow application onto data providers.

For example, you can have a PersonData-table with a 'personid', 'key' and 'value' column. Another application fills the table with birthdates for people by adding rows with the key 'BirthDate'. A PersonCheckStep in your workflow application allows you to define what you want to do for the key 'BirthDate' and knows how to retrieve the data. You can expand this by having ComputerData for PC settings, LDAPData for LDAP Settings, and so on...


JDT's answer is pretty good, but another option you might want to consider is a domain-specific language (DSL). In this approach you define a simple language to capture your workflows, provide primitives for specialized checks and steps, etc., and then write an engine to interpret and execute them.

By keeping everything in a database, or hard-coded, you calcify the system and make it difficult to introduce variation in workflow. By using a language, provided the language admits the richness you need, you push the complexity to the workflow scripts and keep your engine clean and relatively simple.

Adding more special checks and steps could be handled by something akin to libraries, which provide C# implementations for special work needed by the DSL. Again, you are separating the main workflow (in the DSL script), from the checks and steps (in the libraries), from the engine that runs it all. It should keep the complexity manageable.

As an example, a lot of video games have levels defined in a DSL that is interpreted by the game engine. The allows people without strong programming skills to be productive and create something valuable without requiring the most expensive developers to implement all the features of each particular level.


The question you should be asking yourself is if the effort saved on maintenance (by not having to change code for future user requests) or the additional versatility (such as being able to easily convert and market the app to different users) are worth the additional effort of creating a more generalized system. Don't write a universal condiment dispensing factory when someone asks you to pass the salt.

Another option to think about is making sure the architecture can handle customization, but make a hardcoded version first and worry about creating an administrative interface later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.