Base solution for your next web application
Open Closed

Seeking an advice - Workflow Foundation integration #3909


User avatar
0
bilalhaidar created

Hi, I am trying to integrate Workflow Foundation to ASPNETZERO, basically on the AppService level.

I just need your guidance when it comes to organizing the code.

Shall I create a new Class Library with a Module, add all the Workflow code there, and then add this module as a dependency on the AppService module? Would that work fine? Or there are other considerations I am not able to see in here?

Thanks Bilal


7 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @bilalhaidar,

    Integrating a workflow mechanism into AspNet Zero is a big job and we don't have any experience on this area at the moment. I suggest you to search this on the web. If you can come up with an example scenario, maybe we can suggest you something.

    Thanks.

  • User Avatar
    0
    bilalhaidar created

    Sounds great Ismail

    I did a research today and found stateless 3.0 hosted over github.com. It's a state machine implementation in c# and could be used to define such work flows by code.

    Its a simple state machine but good enough for me to define a workflow and do things like send email for a task with link to Form, create a task object for users, include My Inbox and other simple features.

    Can I do all this coding stuff in a new module and add it as dependency to AppService so as not to clutter AppService with workflow stuff? Or what's the recommendation for including new modules?

    Thanks

  • User Avatar
    0
    strix20 created

    <cite>bilalhaidar: </cite> Sounds great Ismail

    I did a research today and found stateless 3.0 hosted over github.com. It's a state machine implementation in c# and could be used to define such work flows by code.

    Its a simple state machine but good enough for me to define a workflow and do things like send email for a task with link to Form, create a task object for users, include My Inbox and other simple features.

    Can I do all this coding stuff in a new module and add it as dependency to AppService so as not to clutter AppService with workflow stuff? Or what's the recommendation for including new modules?

    Thanks

    Have you thought up a way to cleanly transition to treat views as part of the state? This seems like a library that could also be some use to us as well, but it seems less well-suited to asp.net.

    I could see building state into application layer objects, but I'm not sure how you would trigger state transitions to cause view changes?

    I suppose you could build a redirect utility and incorporate that in the state transitions?

  • User Avatar
    0
    bilalhaidar created

    Hello @strix20,

    Let me share with you some details and we can take it from there.

    The problem I am solving is:

    • Coordinator creates a new "Assignment". This assignment is linked to a member in his/her team.
    • The member receives a new task for the "Assignment", fills in some fields on the "Assignment" form and submit again for the Coordinator
    • The coordinator receives a new task for the "Assignment", fills in some fields on the "Assignment" form and finalizes the "Assignment".

    The State Machine could be represented as:

    • Open State
    • At the Member's side State
    • At the Coordinator's side State
    • Closed State

    The "Assignment" entity will contain properties for the section filled by Coordinator first time he/she is creating a new Assignment. Also properties for the section filled by Member and finally more properties filled by Coordinator when they receive the "Assignment" and about to finalize it.

    In my case, I have a simple linear workflow. In future workflows, I might have scenarios where a user could return back the task, etc.

    So using the Stateless 3.0, I could create an AssignmentWorkflow class wrapping the StateMachine class (offered by Stateless) and configure the workflow states and what transitions are permitted (Check the BugTracking example from the Stateless 3.0 GitHub). The AssignmentWorkflow class receives an input of "State" to know at which State to start the StateMachine.

    Also, there will be an input for this StateMachine maybe something like Initiator Username and Next Assignee Username, or any additional informatio needed (to be packed in one object input parameter) etc.

    The AssignmentWorkflow will expose some public methods. One of them is "AssignToMember".

    On the "OnEntry" for this State, the code will:

    • Send email to the assignee with a link to the Assignment Form
    • Create a new "Task" object containing "From, To, etc.". (using a Repository or Manager - Unit of Work)
    • Set the "State" property on the "AssignmentForm" to be "At the Member's side". (using a Repository or Manager - Unit of Work)

    The AssignmentAppService class will contain 2 methods. One to create initially the Assignment and another to handl any future submit on the workflow.

    • When the user logs in to the app, they will have My Inbox. The My Inbox lists all "Task" objects that have "To" assigned to the logged-in user.
    • Clicking on a Task opens the "Assignment Form".
    • When the user opens the form, the app loads the State property from the "AssignmentForm" and decide which sections to show/hide on the Form. I am using Angualr 2 components, so in this case I will have 3 components. One section is used by Coordinator the first time he/she submits a new Assignment. One section is used by Member and a 3rd section used again by Coordinator when they want to finalize the Assignment. Based on the State value, I will show/hide sections.

    The memebr submits the Assignment Form passing the Task Id. The AppService method retrieves the Task object from DB, creates a new instance of the AssignmentWorkflow class passing to it the current State. Then the code triggers on the next State by calling "AssignToCoordinator". The "OnEntry" method for this state would do something similar to the above and proceed.

    How does it sound? I appreciate your feedback.

    Regards Bilal

  • User Avatar
    0
    strix20 created

    It sounds similar to how I'm looking at using it, with the exception that I don't think wrapping the state machine is necessary.

    In our case, however, we will need to transition around various MVC views after state transitions, so I'm trying to figure out the best way to accomplish that (we are not using angular.)

  • User Avatar
    0
    bilalhaidar created

    Encapsulation for the StateMachine is handy to allow you to provide Workflow Actions methods to be used from outside.

    As for the Views, why not use 1 View instead of composing multiple views?

    One thing I dunno if it could help, for each Trigger you can pass in "data". Why not include list of Views to be dislpayed for the user. Then, the client-side would take the list and compose the full view?

    From experience in this field, we tend to use 1 Form and based on State of Workflow, we know what to show/hide, etc.

    I am working now on the Workflow and found myself stuck with something, dunno if you can assist. The wrapper "AssignmentWorkflow" accepts an Entity of type "Assignment". I found myself in need for the IRepository inside this class. Given the ASPNETZERO template, how can I inject the IRepository in a time the class is expecting an entity?

    Shall I define event delegates on this new class in such a way that, I handle OnEntry of each State I have outside that class from the caller side?

    Even I thought of using EventBus, but again, this has to be injected. The problem is I cannot make the AssignmentWorkflow injectable as it expets an Entity in the constructor, or maybe I should change that to something else?

    Bilal

  • User Avatar
    0
    bilalhaidar created

    I might have a solution:

    I have an AssignmentWorkflow that wraps a StateMachine. I found the wrapper useful because I can encapsulate the StateMachine configuration of states, triggers, and handlers for OnEntry.

    The AssignmentWorkflow object will accept the entity Assignment to be able to read from it the current State of the Workflow.

    At the same time, I need to use things like IRepository, ILogger, etc.

    Since I need to make use of DI, I would rather go for this solution.

    • Remove the initialization of the StateMachine from constructor
    • Move the initialization of the StateMachine inside the "AssignToMember" public method. Inside this method, I will create a new StateMachine based on the State passed to "AssignToMember", and any other exposed method. So the StateMachine will be created per Trigger.
    • Configure the StateMachine with the same States (I will use an internal method to do so instead of repeating same code again and again)
    • Attach the event handlers for OnEntry for the States to methods exposed on a Dependency called "IAssignmentWorkflowHandler".
    • Finally, fire the StateMachine.Fire method with a specific Trigger.

    This way, every exposed method representing a trigger "AssignToMember", "AssignToCoordinator", etc. would be creating a new instance of the StateMachine, and firing a certain trigger, etc.

    This way, I encapsulated all my logic to connect to Database and using Abp DI through the use of IAssignmentWorkflowHandler, therefore, the AssignmentWorkflow would delegate all the logic to the IAssignmentWorkflowHandler.

    How does it sound?