2 Stimmen

Ist es möglich, einen in Workflow Foundation erstellten Zustandsautomaten mit Nhibernate in einer DB zu persistieren?

Ich habe eine Anwendung, die bei der Ausführung mehrere Zustandsautomateninstanzen enthält. Ich möchte, dass diese implizit in einer Datenbank gespeichert werden, damit sie bei einem Neustart der Anwendung aus der Datenbank neu geladen werden können und in demselben Zustand fortgesetzt werden, in dem sie beendet wurden, zusammen mit allen Objekteigenschaften, die festgelegt wurden, während die Instanz im Speicher war.

Ist so etwas möglich?

Ich habe Google vergeblich durchsucht, was eines von drei Dingen bedeutet:

  1. Das ist unmöglich!
  2. Ich bin schrecklich im Umgang mit Google
  3. Eine vernünftige Antwort auf diese Frage wird vielen anderen Leuten helfen

Ich hoffe, die Antwort ist 3 :)

3voto

Pieter van Ginkel Punkte 28696

Ja, das ist es, aber es ist kein Zuckerschlecken.

Ich habe diese Umsetzung in Angriff genommen, und es hat viel Arbeit gekostet, sie zu verwirklichen. Ich werde nicht die gesamte Implementierung zur Verfügung stellen (viel Code und Geheimhaltung), aber ich werde die Bausteine nennen, die mich zum Endergebnis geführt haben.

  • http://msdn.microsoft.com/en-us/library/dd483375.aspx gelegen in WF_WCF_Samples\WF\Application\PurchaseProcess\CodedWorkflow\CS\WfDefinition\XmlWorkflowInstanceStore.cs hat einen XML-Persister für den Workflow. Dies umgeht das Problem der Notwendigkeit, die SQL-Tabellen zu haben, und lässt Sie das Ganze einfach in einem XML-Blob speichern;

  • Dieser Serialisierer (de)serialisiert den Code mit einer NetDataContractSerializer . Dieser Serialisierer muss über eine SurrogateSelector Set, mit dem Sie Ihre Entitäten übersetzen. Das Problem ist, dass Sie Ihre Entitäten nicht speichern wollen. Abgesehen davon, dass alle Lazy Entities zusammen mit Ihrer Entität serialisiert werden würden, wäre Ihre Entität zu dem Zeitpunkt, an dem Ihr XML deserialisiert wird, nicht mehr aktuell. Was Sie stattdessen wollen, ist, dass nur die interne ID serialisiert wird. Sie implementieren also eine SurrogateSelector die prüft, ob das zu serialisierende Objekt eine Entität ist. Wenn ja, ersetzen Sie sie durch eine andere Klasse, z.B. EntityReference die den Typ und die ID enthält;

  • Wenn die XML-Datei deserialisiert wird, mit demselben SurrogateSelector suchen Sie nach Instanzen von EntityReference . Wenn Sie das finden, machen Sie eine ISession.Load() mit dem Typ und der ID in der Referenz und geben diese anstelle der Referenz zurück.

Dies sind die Grundbausteine für die Serialisierung und Deserialisierung des Workflows. Das ist kein einfaches Unterfangen, aber mit diesen Teilen habe ich es hinbekommen.

Ich hoffe, das hilft Ihnen.

2voto

Sisyphus Punkte 4073

Nhibernate ist dafür nicht besonders nützlich, da die physische Persistenzoperation ein kleiner Aspekt der Workflow-Persistenz ist. Der beteiligte Teil sind alle Dienste, die das Entladen, das Neuladen und das Aktivieren von Workflows zu den entsprechenden Zeitpunkten usw. unterstützen. Das Innenleben der Laufzeit und der Dienste wird auch durch die Tatsache kompliziert, dass Workflows Anwendungsgrenzen überspannen, die unendlich lange dauern können. Verschiedene Entitäten können sich zu jedem Zeitpunkt in unterschiedlichen Zuständen befinden. Da nicht garantiert werden kann, dass ein Aufruf unter diesen Bedingungen überhaupt einen Client hat, legt die Laufzeit beispielsweise beim Auslösen eines Ereignisses in einem Workflow eine Nachricht in eine Warteschlange, anstatt einen eigentlichen Funktionszeiger aufzurufen. Auf diese Weise können Sie ein Ereignis in einem nicht laufenden Workflow "auslösen".

Sie können auf diese Nachrichtenwarteschlangen und andere Low-Level-Details der Laufzeiten zugreifen, aber es ist wahrscheinlich am besten zu versuchen, innerhalb des Microsoft-Rahmens zu bleiben und zu vermeiden, alles so weit wie möglich neu zu bauen. Si, wenn Sie die Dinge auf ihre Art und Weise tun, was viel einfacher ist, als zu versuchen, es selbst zu verwalten, wird Nhibernate ziemlich sinnlos, weil alles, was es tun würde, ist ein binärer Serialisierungsstrom persistieren.

Zu den verschiedenen verfügbaren Erweiterungen gehört auch die Möglichkeit, benutzerdefinierte Persistenzanbieter zu erstellen, die innerhalb des bestehenden Workflow-Frameworks arbeiten können. Es gibt bereits einen Oracle-Anbieter. Ich kann nicht bestätigen, dass er zuverlässig ist, aber Sie sollten zumindest in der Lage sein, auf ihm aufzubauen.

http://wftools.codeplex.com/

0voto

rvxnet Punkte 447

Wäre dies eine geeignete Lösung?

Mit der FilePersistence.cs benutzerdefinierte Persistenz Handler entdeckte ich in den Download-Link auf den folgenden Artikel:

http://msdn.microsoft.com/en-us/library/ms741725%28v=VS.85%29.aspx

   public class FilePersistenceService : WorkflowPersistenceService
{

    public FilePersistenceService(bool unloadOnIdle)
    {
       // ...
    }

    protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock)
    {
        // ...
    }

    private void ReloadWorkflow(object id)
    {
        // ...
    }

    protected override Activity LoadWorkflowInstanceState(Guid instanceId)
    {
        // ...
    }

    protected override void UnlockWorkflowInstanceState(Activity state)
    {
        // ...
    }

    protected override void SaveCompletedContextActivity(Activity activity)
    {
        // ...
    }

    protected override Activity LoadCompletedContextActivity(Guid activityId, Activity outerActivity)
    {
        // ...

    }

    protected override bool UnloadOnIdle(Activity activity)
    {
        // ...
    }

    private void SerializeToFile(byte[] workflowBytes, Guid id)
    {
        // ... Direct workflowBytes to DB, indexed by Guid
    }

    private byte[] DeserializeFromFile(Guid id)
    {
        // ... Load bytes from DB, by Guid
    }

}

... die SerializeToFile und DeserializeFromFile überschreiben, um die Aufrufe in eine DB und nicht in das Dateisystem umzuleiten.

Ich würde wahrscheinlich NHibernate verwenden, um das Laden/Speichern zu erreichen - um meine DAL gemeinsam über die Anwendung zu halten und hoffentlich DB-Unabhängigkeit zu halten (sollte es erforderlich sein, eine andere DB-Plattform zu verwenden).

Hat dieser Plan irgendwelche größeren Mängel?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X