简体   繁体   中英

How can I model and structure this workflow engine?

I'm trying to come up with (what I hoped to be) a somewhat simple workflow engine.

Basically I have an object of a class with a Status property. In order for it to advance to a different status it should go through a validation step. If there's no validation errors, status would be changed.

During the validation, though, I would like to allow the validator component to request information from the user or issue an alert message.

My problem is that as of now the application is built as a Windows Forms application but we know that it will be necessary to have a web version of it. So, the validation will be the same for both, but each should be allowed to have it's own way to request information or and alert the user. The way I imagined to do this is to use delegates and events on my validation classes.

Here's what I got:

//This is the class which will have its status changed
public class MyClass
{
  public int Status { get; set; }
}

//This class represent a transition from one status to another
public class Transition
{
  public int FromStatus { get; set; }
  public int ToStatus { get; set; }
}

//Common interface for all validators
public interface IWorkflowValidator
{
  bool Validate(MyClass object);
}

//This is the base workflow class with the main logic
public abstract class BaseWorkflow
{
  //This holds all the possible transitions with the validator type responsible for its validation.
  //For example:
  //  var transition = new Transition(1, 2); //From 1 to 2
  //  validatorsMap.Add(transition, typeof(ValidatorFrom1To2)); //ValidatorFrom1To2 class would be used to validate transition from status 1 to 2.
  protected Dictionary<Transition, Type> validatorsMap = null;

  //Main logic for a transition
  public void PerformTransition(MyClass object, int ToStatus)
  {
    int currentStatus = object.Status;
    var requestedTransition = new Transition(currentStatus, ToStatus);

    //Get the validator specified for this transition
    var validatorType = validatorsMap[requestedTransition];

    //Instantiate a new validator of that type
    var validator = (IWorkflowValidator)Activator.CreateInstance(validatorType);

    //Gets the result of the validator
    bool results = validator.Validate(object);

    //If validation succeded, it will perform the transition and complete the execution
  }
}

My main question concerns the validator itself. As I said, I need the validator to be able to request information required by specific transitions. So, this is how I have my first validator:

public class AlertHandlerArguments {}

public delegate void AlertHandler(AlertHandlerArguments args);

public class MyFirstValidator : IWorkflowValidator
{
  //Event used to send an alert to the user
  public event AlertHandler OnAlert;

  //Implementation of IWorkflowValidator
  public bool Validate(MyClass object)
  {
    SendAlert();
  }

  void SendAlert()
  {
    if (OnAlert != null)
      OnAlert(new AlertHandlerArguments());
  }
}

What I'm thinking here is to create an interface with all types of events and implement those on all validators. Then my abstract BaseWorkflow class can attach handlers for those events.

However, my abstract class cannot implement the final code for those events. Those are meant to be used by the interface and so far my abstract class is platform independent (desktop, web). That's actually the reason why I created this class as abstract.

With that I can have my Windows Forms project to have a concrete type of BaseWorkflow and attach events to display Form objects to request information.

Another option would be to attach handlers on the base class and override on the concrete class at the UI level.

Am I going in the right direction? How can I allow the validator to request information from the user (at the UI level) keeping some logic at the business layer so that it fits windows forms and web?

I appreciate any input on the matter. Thanks in advance.

Ps.: Only after I finished writing I realized that I'm not really sure on how to use this on a web application. I mean, a Windows Forms application can interrupt execution and display an input form for a user but that won't work on the web. Does that mean my workflow structure is only viable for desktop applications?

First of all, if you want use the various validators inside your workflow, and validator will depend from the environment => so you probably need to Strategy pattern. But you need to be carefull with that.

Creating interface with all types of events is probably not a perfect idea because of an overkill of the things to do. Beter that validator should have some public state and that state could depend from validation result and then workflow should just check validator state. And instead of using events I just think that it will be better to use delegate as function argument.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM