Freigeben über


Vorwärtsverketten von Regeln

Verkettung basiert auf den identifizierten Abhängigkeiten zwischen Regeln; genauer gesagt die Abhängigkeiten zwischen den Aktionen einer Regel und den Bedingungen anderer Regeln. Diese Abhängigkeiten können mithilfe von drei Methoden identifiziert oder deklariert werden:

  • Implizit

  • Attributbasiert

  • Explizit

Implizit

Implizite Abhängigkeiten werden automatisch vom Workflow-Laufzeitmodul identifiziert. Bei der ersten Ausführung von RuleSet wird jede Regel analysiert, um die Felder bzw. Eigenschaften, die in der Bedingung gelesen und in die Aktionen geschrieben werden, zu bewerten. Dies geschieht durch Durchlaufen des Ausdrucks in der Bedingung und den Anweisungen in den Aktionen. Nehmen Sie beispielsweise die folgenden Regeln an:

Rule 1
IF this.discount > 0
THEN this.total = (1-this.discount) * this.subtotal

Rule 2
IF this.subtotal > 10000
THEN this.discount = 0.05

Das Workflow-Laufzeitmodul wertet die Regeln aus und stellt fest, dass Regel 1 den Inhalt der Rabatt- und Teilergebnisfelder liest und ihn in das Gesamtergebnisfeld schreibt. Regel 2 liest das Teilergebnisfeld und führt einen Schreibvorgang im Rabattfeld durch; daher ist Regel 1 von Regel 2 abhängig. Daraus folgt, dass durch das Workflow-Laufzeitmodul sichergestellt wird, dass Regel 1 ausgewertet oder neu ausgewertet wird, wenn Regel 2 die Then-Aktion ausführt.

Abhängigkeiten werden auf Blattknotenebene identifiziert (siehe folgendes RuleSet-Beispiel).

Rule 1
IF this.order.Discount > 0
THEN this.order.Total = (1-this.order.Discount) * this.order.Subtotal

Rule 2
IF this.order.Subtotal > 10000
THEN this.order.Discount= 0.05

Rule 3 
IF this.order.CustomerType = "Residential"
THEN ...

Eine Abhängigkeit wird nach wie vor zwischen den Regeln 1 und 2 identifiziert. Allerdings ist Regel 3 nicht von Regel 1 oder 2 abhängig, da von keiner dieser Regeln die CustomerType-Eigenschaft aktualisiert wird. Die Abhängigkeit wird also auf der Ebene der CustomerType-Eigenschaft und nicht auf der Ebene des Order-Objekts selbst identifiziert.

Durch implizites Verketten nimmt Windows Workflow Foundation dem Benutzer den Großteil der erforderlichen Verkettung ab. Daher muss der Benutzer nicht explizit Modelle von Aktualisierungen erstellen und ist von Verkettungsaufgaben in der Regel entbunden. Dadurch wird das Erstellen von Modellen komplexer Regelsätze vereinfacht. Es handelt sich dabei um eine weitgehend verborgene Funktion des Workflow-Laufzeitmoduls.

Die zwei anderen Mechanismen zur Durchführung von Verkettungen, attributbasiert und explizit, sind für komplexere und speziellere Szenarien vorgesehen.

Attributbasiert

Für Methodenaufrufe innerhalb einer Regel wird es schwieriger, die auftretenden Lese- und Schreibvorgänge deterministisch auszuwerten. Zum Umgang mit diesem Problem bietet Windows Workflow Foundation drei Attribute, die auf eine Methode angewendet werden können, um die Aktionen anzugeben:

  • RuleRead

  • RuleWrite

  • RuleInvoke

Durch das Zuweisen des RuleReadAttribute-Attributs zu einer Methode wird angegeben, dass die angegebene Eigenschaft gelesen wird. Auf ähnliche Weise kann mit dem RuleWriteAttribute-Attribut angegeben werden, dass eine Methode ein bestimmtes Feld oder eine Eigenschaft aktualisiert. Nehmen Sie an, dass die ersten zwei Regeln unter dem impliziten Abschnitt folgendermaßen umgeschrieben wurden:

Rule 1
IF this.discount > 0
THEN this.total = (1-this.discount) * this.subtotal

Rule 2
IF this.subtotal > 10000
THEN this.SetDiscount(0.05)

Die SetDiscount-Methode kann anschließend folgendermaßen zugewiesen werden. Dadurch kann das Modul feststellen, dass Regel 1 aufgrund der Verwendung des Rabattfelds von Regel 2 abhängig ist.

[RuleWrite("discount")] 
void SetDiscount(double requestedDiscount)
{
...//Some code that updates the discount field.
}

Das RuleInvokeAttribute-Attribut kann verwendet werden, um Abhängigkeiten vorzuschreiben, die von verknüpften Methodenaufrufen verursacht werden. Nehmen Sie die folgende Änderung zum Beispiel an den Regeln und Methoden an:

Rule 1
IF this.discount > 0
THEN this.total = (1-this.discount) * this.subtotal

Rule 2
IF this.subtotal > 10000
THEN this.SetDiscountWrapper(0.05)

[RuleInvoke("SetDiscount")]
void SetDiscountWrapper(double requestedDiscount)
{
     ...
     SetDiscount(requestedDiscount);
     ...
}

[RuleWrite("discount")] 
void SetDiscount(double requestedDiscount)
{
}

Mit der Aktion von Regel 2 wird SetDiscountWrapper aufgerufen. Dadurch wird wiederum SetDiscount aufgerufen, das ins Rabattfeld geschrieben wird. Das RuleInvokeAttribute-Attribut ermöglicht das Deklarieren und Erkennen dieses indirekten Schreibvorgangs durch das Workflow-Laufzeitmodul.

Das Feld oder die Eigenschaft, auf das bzw. die im Attributpfad verwiesen wird, bezieht sich auf ein Feld oder eine Eigenschaft, das in derselben Klasse wie die Methode enthalten ist. Dies ist nicht notwendigerweise das an RuleSet zur Ausführung übergebene Stammobjekt. Zum Beispiel können der Order-Klasse folgendermaßen zugewiesen werden:

public class Order
{
     private double discount;

     public double Discount
     {
         get { return discount;}
         set { discount = value;}
     }

     [RuleWrite("Discount")] 
     void CalculateDiscount(double requestedDiscount, double weighting)
     {
...       //Some code that updates the discount field.
     }
}

Anschließend kann eine Instanz dieser Klasse folgendermaßen in einem Workflow verwendet werden:

public class Workflow1 : SequentialWorkflowActivity
{
     private Order discount;
     ...
}

Die Ausführung von Regel 2 verursacht die erneute Auswertung von Regel 1:

Rule 1
IF this.order.Discount > 5
THEN ...

Rule 2
IF ...
THEN this.order.CalculateDiscount( 5.0, .7)

Verwenden von Attributen

Einige zusätzliche Anmerkungen zur Verwendung von Attributen:

  • Mit Attributen wird die Verwendungsweise von Parametern in der Methode angegeben. Beispielsweise wird die folgende Methode zugewiesen, um anzugeben, dass die Rabatteigenschaft in der übergebenen Bestellinstanz geändert wird.

    [RuleWrite("currentOrder/Discount", RuleAttributeTarget.Parameter)]
    private void SetDiscount(Order currentOrder, double discount)
    {
        currentOrder.Discount = discount;
    }
    
  • Platzhalterzeichen können auch in den Regelattributen verwendet werden. Beispielsweise kann mit RuleWrite("order/*") angegeben werden, dass alle Felder in dem Objekt, auf das im Feld für die Reihenfolge verwiesen wird, von der Methode geändert werden. Allerdings kann das Platzhalterzeichen nur am Ende des Pfads verwendet werden; ein Attribut wie RuleWrite("*/Discount") ist ungültig.

  • Ein Attribut wie RuleWrite("order") kann mit Verweistypen verwendet werden, um anzugeben, dass der Verweis geändert wurde, beispielsweise, um anzugeben, dass die Variable nun auf eine andere Order-Instanz verweist. Angenommen wird, dass alle Regeln, die ein Feld bzw. eine Eigenschaft in der Variable verwenden, betroffen sind (neben allen Regeln, die den Instanzverweis selbst testen; beispielsweise IF this.order == this.order2).

  • Sofern keine Methodenattribute angegeben sind, wird als Standardverhalten angenommen, dass von einem Methodenaufruf keine Felder bzw. Eigenschaften im Zielobjekt gelesen oder geschrieben werden (das Objekt, in dem die Methode aufgerufen wird). Darüber hinaus wird angenommen, dass vom Methodenaufruf Parameter gemäß Schlüsselwörtern gelesen und geschrieben werden (ref, out, ByVal, ByRef usw.), die in .NET Framework definiert sind.

Explizit

Als abschließender Mechanismus für die Angabe von Feld- und Eigenschaftenabhängigkeiten dient die Update-Anweisung. Für die Update-Anweisung wird als Argument entweder eine Zeichenfolge verwendet, bei der es sich um den Pfad zu einem Feld, einer Eigenschaft oder einem Ausdruck handelt, das/die/der einen Feld- bzw. Eigenschaftenzugriff darstellt. Beispielsweise kann eine der folgenden beiden Anweisungen in den RuleSet-Editor eingegeben werden, um eine Update-Anweisung für die Name-Eigenschaft einer Customer-Instanz im Workflow zu erstellen.

Update("this/customer/Name") 
OR
Update(this.customer.Name)

Hinweis

Der RuleSet-Editor zeigt das Update immer als Update("dieser/Kunde/Name") an.

Die Update-Anweisung gibt an, dass die Regel einen Schreibvorgang im angegebenen Feld bzw. der Eigenschaft durchführt. Dies hat dieselbe Auswirkung wie ein direkter Satz des Felds bzw. der Eigenschaft in der Regel oder das Aufrufen einer Methode mit RuleWriteAttribute für das Feld bzw. die Eigenschaft.

Die Update-Anweisung unterstützt auch die Verwendung von Platzhalterzeichen. Zum Beispiel können Sie einer Regel die folgende Update-Anweisung hinzufügen:

Update("this/customer/*")

Dadurch wird veranlasst, dass alle Regeln, von denen eine beliebige Eigenschaft in der Customer-Instanz in ihren Bedingungen verwendet wird, erneut ausgewertet werden. Dies bedeutet also, dass die folgenden zwei Regeln neu ausgewertet werden:

IF this.customer.ZipCode == 98052
THEN ...

IF this.customer.CreditScore < 600
THEN ...

Im Allgemeinen ist in den meisten Szenarien keine Erstellung von Modellen expliziter Update-Anweisungen erforderlich; die erforderliche Abhängigkeitsanalyse und die Verkettung werden in der Regel durch implizite Verkettung bereitgestellt. Methodenzuweisung sollte die wichtigsten Szenarien unterstützen, in denen die Abhängigkeiten von impliziter Verkettung nicht identifiziert werden können. Im Allgemeinen ist die Methodenzuweisung die bevorzugte Methode, um Abhängigkeiten mithilfe der Update-Anweisung anzugeben, da die Abhängigkeit einmal auf der Methode identifiziert und in zahlreichen verschiedenen Regeln, von denen diese Methode genutzt wird, verwendet werden kann. In Szenarien, in denen es sich beim Ersteller der Regel und beim Implementierenden der Methode um verschiedene Personen handelt (oder in denen die Tätigkeit zu verschiedenen Zeiten ausgeführt wird), erhält der Methodenersteller durch die Methodenzuweisung zudem genauere Kenntnisse des Codes und kann dadurch die Abhängigkeiten der Methode identifizieren.

Allerdings gibt es einige Szenarien, in denen die Update-Anweisung die geeignete Lösung ist. Dies ist beispielsweise der Fall, wenn ein Feld bzw. eine Eigenschaft einer Methode in einer Klasse übergeben wird, die Sie als Ersteller des Workflows nicht steuern und daher nicht zuweisen können. Dies wird im folgenden Beispiel dargestellt.

IF ...
THEN this.customer.UpdateCreditScore(this.currentCreditScore)
Update(this.currentCreditScore)

Siehe auch

Referenz

RuleSet
RuleUpdateAction
RuleHaltAction
RuleWriteAttribute
RuleReadAttribute
RuleReadWriteAttribute
RuleInvokeAttribute

Konzepte

Verwenden von RuleSets in Workflows
Regelauswertung in RuleSets

Footer image

Copyright © 2007 by Microsoft Corporation. Alle Rechte vorbehalten.