locked
How to proper use the persistance in a generic way. RRS feed

  • Question

  • When we want to resume a idled persisted workflow, we need to do this king of code :

    application = new WorkflowApplication(workflow);
    application.InstanceStore = instanceStore;
    application.Load(id);

    So we can see the constructor of the WorkflowApplication need to original activity (or copy...) instance before loading the instance. What I try to do is being generic, so we can retreive the workflow type / instance / xml by the storing some additional datas with the workflow (for exemple, the id to the workflow xml in the database). So I though using a PersistenceParticipant extension. But since I need to have the activity instance before anything else, I guess this won't work. So what would be the best strategy for this?

    Monday, November 2, 2009 9:37 PM

Answers

  • At this point, the two best options here are to:

    1) Remove that requirement.  Come up with a design that allows you to always have the workflow definition first.
    2) Keep your own table or use one of the SqlWorkflowInstanceStore's queriable views to get the activity before creating the WorkflowApplication.

    In the second case you end up doing two DB roundtrips (which is regrettable), but that is where we are at this point.  You can write your own host by directly subclassing WorkflowInstance, but that is a hole that I would not recommend going down unless you are prepared to write a lot of tricky code.

    So, the above would end up looking something like:

    int workflowXmlId = RunDefinitionQuery(workflowInstanceId);
    Activity workflow = GetWorkflowDefinition(workflowXmlId);
    WorkflowApplication application = new WorkflowApplication(workflow);
    application.InstanceStore = instanceStore;
    application.Load(id);
    • Marked as answer by Instriker Tuesday, November 3, 2009 3:09 PM
    Tuesday, November 3, 2009 12:37 AM

All replies

  • At this point, the two best options here are to:

    1) Remove that requirement.  Come up with a design that allows you to always have the workflow definition first.
    2) Keep your own table or use one of the SqlWorkflowInstanceStore's queriable views to get the activity before creating the WorkflowApplication.

    In the second case you end up doing two DB roundtrips (which is regrettable), but that is where we are at this point.  You can write your own host by directly subclassing WorkflowInstance, but that is a hole that I would not recommend going down unless you are prepared to write a lot of tricky code.

    So, the above would end up looking something like:

    int workflowXmlId = RunDefinitionQuery(workflowInstanceId);
    Activity workflow = GetWorkflowDefinition(workflowXmlId);
    WorkflowApplication application = new WorkflowApplication(workflow);
    application.InstanceStore = instanceStore;
    application.Load(id);
    • Marked as answer by Instriker Tuesday, November 3, 2009 3:09 PM
    Tuesday, November 3, 2009 12:37 AM
  • Option 1 isn't really an option for us. We want to remove the technical problems of workflows (thread management, how to load correctly, ...) in our applications and keep them in our library. So in this point of view, we want something as easy to use as ".Create (xml), .GetResults (), .Resume (), ...". Also, in 3.5, we were already offring this kind of API, and we don't want to break our applications.

    If I keep my own table will need to try to sync workflow tables with ours, but I'm not sure it will be quite easy to ensure consistency.

    So I think using the queriable views [System.Activities.DurableInstancing].[InstancePromotedProperties] will be the best for my case. Even if it's an aditionnal db roundtrip to get our definitionid, I don't think it will affect performance since it's not a frequent operation. We can also use caching to help us in the worst cases (we already cache the xml for each id). But at least it will be implemented in a standard way to better support maintenance.
    Tuesday, November 3, 2009 3:08 PM