Erstellen eines Faktenabrufers
Ein Faktenabrufer ist eine Komponente, mit deren Hilfe Instanzen langfristiger Fakten an eine Richtlinie übergeben werden, wenn diese ausgeführt wird. Sie können die IFactRetriever-Schnittstelle implementieren und eine Richtlinienversion so konfigurieren, dass diese Implementierung zur Laufzeit verwendet wird, um die langfristigen Fakteninstanzen einzubringen. Die Richtlinienversion ruft die UpdateFacts-Methode der Fact Retriever-Implementierung in jedem Ausführungszyklus auf, wenn ein Faktenabruf für diese bestimmte Version konfiguriert ist.
Optional können Sie die IFactRemover-Schnittstelle für eine Fact Retriever-Komponente implementieren. Die Regel-Engine ruft die UpdateFactsAfterExecution-Methode der IFactRemover-Schnittstelle auf, wenn die Richtlinie verworfen wird. Dies bietet die Möglichkeit zum Durchführen von Aktionen nach der Ausführung, z. B. das Ausführen von Commits für Datenbankänderungen oder das Zurückziehen von Objektinstanzen aus dem Arbeitsspeicher der Regel-Engine.
So legen Sie einen Faktenabrufer für eine Richtlinie fest
Mithilfe des folgenden Codes können Sie den Regelsatz so konfigurieren, dass eine Klasse namens "Retriever" in der Assembly namens "MyAssembly" als Faktenabrufer verwendet wird.
RuleEngineComponentConfiguration fr = new RuleEngineComponentConfiguration("MyAssembly", "Retriever");
RuleSet rs = new RuleSet("ruleset");
// associate the execution configuration with a ruleset
RuleSetExecutionConfiguration rsCfg = rs.ExecutionConfiguration;
rsCfg.FactRetriever = factRetriever;
Hinweis
Wenn Sie einen einfachen Assemblynamen (wie MeineAssembly) als ersten Parameter für den Konstruktor RuleEngineComponentConfiguration angeben, geht das BizTalk-Regelmodul davon aus, dass es sich um eine private Assembly handelt und sucht in Ihrem Anwendungsordner nach der Assembly. Wenn Sie einen vollqualifizierten Assemblynamen wie MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a310908b42c024fe angeben, geht die Regel-Engine davon aus, dass es sich um eine freigegebene Assembly handelt, und sucht im globalen Assemblycache (GAC) nach der Assembly. Die Definitionen von einfachen und vollqualifizierten Assemblynamen finden Sie unter https://go.microsoft.com/fwlink/?LinkId=64535.
Den Faktenabrufer können Sie mit der erforderlichen anwendungsspezifischen Logik entwerfen, um eine Verbindung mit den benötigten Datenquellen herzustellen, die Daten als langfristige Fakten an die Engine zu übergeben und die Logik für das Aktualisieren oder Übergeben neuer Instanzen langfristiger Fakten im bzw. an die Engine festzulegen. Bis zu ihrer Aktualisierung werden die Werte, die anfangs an die Engine übergeben und folglich zwischengespeichert werden, bei nachfolgenden Ausführungszyklen verwendet. Die Fact Retriever-Implementierung gibt ein Objekt zurück, das einem Token entspricht und zusammen mit dem factsHandleIn-Objekt verwendet werden kann, um zu bestimmen, ob vorhandene Fakten aktualisiert oder neue Fakten bestätigt werden. Wenn eine Richtlinienversion den Fact Retriever zum ersten Mal aufruft, ist das factsHandleIn-Objekt immer NULL und nimmt dann den Wert des Rückgabeobjekts nach der Ausführung des Faktenabrufers an.
Beachten Sie, dass für ein und dieselbe Instanz der Regel-Engine ein langfristiger Fakt nur einmal übergeben werden muss. Wenn Sie z. B. das Shape Aufrufregeln in einer Orchestrierung verwenden, wird die instance Richtlinie in einen internen Cache verschoben. Zu diesem Zeitpunkt werden alle kurzfristigen Fakten zurückgezogen. Langfristige Fakten werden aufbewahrt. Wird dieselbe Richtlinie erneut aufgerufen, entweder durch dieselbe Orchestrierungsinstanz oder eine andere Orchestrierungsinstanz auf demselben Host, wird die Richtlinieninstanz aus dem Cache abgerufen und erneut verwendet. In einigen Szenarien mit Batchverarbeitung können mehrere Instanzen derselben Richtlinie erstellt werden. Wenn eine neue Richtlinieninstanz erstellt wird, müssen Sie sicherstellen, dass die richtigen langfristigen Fakten übergeben werden.
Darüber hinaus müssten Sie benutzerdefinierten Code schreiben, um die folgenden Strategien zu implementieren:
Wissen, wann die langfristigen Fakten zu aktualisieren sind
Nachverfolgen, welche Instanz der Regel-Engine welche langfristigen Fakten verwendet
Der folgende Beispielcode zeigt verschiedene Implementierungen des Faktenabrufers, die "MyPolicy" zugeordnet werden, um "MyTableInstance" mit unterschiedlichen Bindungstypen als langfristigen Fakt zu übergeben.
DataTable-Bindung
using System;
using System.Xml;
using System.Collections;
using Microsoft.RuleEngine;
using System.IO;
using System.Data;
using System.Data.SqlClient;
namespace MyBizTalkApplication.FactRetriever
{
public class myFactRetriever:IFactRetriever
{
public object UpdateFacts(RuleSetInfo rulesetInfo, Microsoft.RuleEngine.RuleEngine engine, object factsHandleIn)
{
object factsHandleOut;
if (factsHandleIn == null)
{
SqlDataAdapter dAdapt = new SqlDataAdapter();
dAdapt.TableMappings.Add("Table", "CustInfo");
SqlConnection conn = new SqlConnection("Initial Catalog=Northwind;Data Source=(local);Integrated Security=SSPI;");
conn.Open();
SqlCommand myCommand = new SqlCommand("SELECT * FROM CustInfo", conn);
myCommand.CommandType = CommandType.Text;
dAdapt.SelectCommand = myCommand;
DataSet ds = new DataSet("Northwind");
dAdapt.Fill(ds);
TypedDataTable tdt = new TypedDataTable(ds.Tables["CustInfo"]);
engine.Assert(tdt);
factsHandleOut = tdt;
}
else
factsHandleOut = factsHandleIn;
return factsHandleOut;
}
}
}
Bindung "DataRow"
using System;
using System.Xml;
using System.Collections;
using Microsoft.RuleEngine;
using System.IO;
using System.Data;
using System.Data.SqlClient;
namespace MyBizTalkApplication.FactRetriever
{
public class myFactRetriever:IFactRetriever
{
public object UpdateFacts(RuleSetInfo rulesetInfo, Microsoft.RuleEngine.RuleEngine engine, object factsHandleIn)
{
object factsHandleOut;
if (factsHandleIn == null)
{
SqlDataAdapter dAdapt = new SqlDataAdapter();
dAdapt.TableMappings.Add("Table", "CustInfo");
SqlConnection conn = new SqlConnection("Initial Catalog=Northwind;Data Source=(local);Integrated Security=SSPI;");
conn.Open();
SqlCommand myCommand = new SqlCommand("SELECT * FROM CustInfo", conn);
myCommand.CommandType = CommandType.Text;
dAdapt.SelectCommand = myCommand;
DataSet ds = new DataSet("Northwind");
dAdapt.Fill(ds);
TypedDataTable tdt = new TypedDataTable(ds.Tables["CustInfo"]);
// binding to the first row of CustInfo table
TypedDataRow tdr = new TypedDataRow(ds.Tables["CustInfo"].Rows[0],tdt);
engine.Assert(tdr);
factsHandleOut = tdr;
}
else
factsHandleOut = factsHandleIn;
return factsHandleOut;
}
}
}
Der folgende Beispielcode veranschaulicht das Übergeben von .NET- und XML-Fakten an eine Implementierung des Faktenabrufers.
using System;
using System.Xml;
using System.Collections;
using Microsoft.RuleEngine;
using System.IO;
using System.Data;
using System.Data.SqlClient;
namespace MyBizTalkApplication.FactRetriever
{
public class myFactRetriever:IFactRetriever
{
public object UpdateFacts(RuleSetInfo rulesetInfo, Microsoft.RuleEngine.RuleEngine engine, object factsHandleIn)
{
object factsHandleOut;
if (factsHandleIn == null)
{
//create .NET object instances
bookInstance = new Book();
magazineInstance = new Magazine();
//create an instance of the XML object
XmlDocument xd = new XmlDocument();
//load the document
xd.Load(@"..\myXMLInstance.xml");
//create and instantiate an instance of TXD
TypedXmlDocument doc = new TypedXmlDocument("mySchema",xd1);
engine.Assert(bookInstance);
engine.Assert(magazineInstance);
engine.Assert(doc);
factsHandleOut = doc;
}
else
factsHandleOut = factsHandleIn;
return factsHandleOut;
}
}
}
Bindung "DataConnection"
using System;
using System.Xml;
using System.Collections;
using Microsoft.RuleEngine;
using System.IO;
using System.Data;
using System.Data.SqlClient;
namespace MyBizTalkApplication.FactRetriever
{
public class myFactRetriever:IFactRetriever
{
public object UpdateFacts(RuleSetInfo rulesetInfo, Microsoft.RuleEngine.RuleEngine engine, object factsHandleIn)
{
object factsHandleOut;
{
string strCmd = "Initial Catalog=Northwind;Data Source=(local);Integrated Security=SSPI;";
SqlConnection conn = new SqlConnection(strCmd);
DataConnection dc = new DataConnection("Northwind", "CustInfo", conn);
engine.Assert(dc);
factsHandleOut = dc;
}
return factsHandleOut;
}
}
}
Beachten Sie, dass DataConnections immer wie im vorherigen Codebeispiel gezeigt erneut überprüft werden sollte, wenn es von einem Faktenre retriever bereitgestellt wird. Die Engine instance verwendet dataConnection, um die Datenbank basierend auf den Regelbedingungen abzufragen, und alle von der Abfrage zurückgegebenen Zeilen werden im Arbeitsspeicher der Engine als TypedDataRowsbestätigt. Durch das erneute Überprüfen von DataConnection wird sichergestellt, dass Zeilen aus einer vorherigen Ausführung der Engine aus dem Arbeitsspeicher gelöscht werden.
In der Tat hat die Durchsetzung einer DataConnection über einen Fakten-Retriever wenig Vorteile, außer dass es eine Möglichkeit zum Externalisieren der Datenquelle bietet.