Partager via


Création d'un extracteur de faits

Un extracteur de faits est un composant utilisé pour déclarer des instances de faits à long terme dans une stratégie, et ce durant l'exécution de celle-ci. Vous pouvez implémenter l’interface IFactRetriever et configurer une version de stratégie pour utiliser cette implémentation au moment de l’exécution afin d’apporter les instances de faits à long terme. La version de stratégie appelle la méthode UpdateFacts de l’implémentation du récupérateur de faits à chaque cycle d’exécution, si un récupérateur de faits est configuré pour cette version particulière.

Vous pouvez éventuellement implémenter l’interface IFactRemover sur un composant fact retriever. Le moteur de règles appelle la méthode UpdateFactsAfterExecution de l’interface IFactRemover lorsque la stratégie est supprimée. Vous avez ainsi la possibilité d'effectuer un certain nombre de tâches après l'exécution, telles que la validation des modifications de base de données ou le retrait d'instances d'objet de la mémoire de travail du moteur de règles.

Spécification d'un extracteur de faits pour une stratégie

Vous pouvez utiliser le code suivant pour configurer l'ensemble de règles permettant d'utiliser une classe appelée « Extracteur » en tant qu'extracteur de faits dans l'assembly appelé « MyAssembly ».

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;

Notes

Si vous spécifiez un nom simple d'assembly tel que MyAssembly comme premier paramètre pour le constructeur RuleEngineComponentConfiguration, le moteur de règles BizTalk suppose qu'il s'agit d'un assembly privé et recherche l'assembly dans votre dossier d'applications. Si vous spécifiez un nom d’assembly complet tel que MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a310908b42c024fe, le moteur de règles suppose qu’il s’agit d’un assembly partagé et recherche l’assembly dans le global assembly cache (GAC). Vous trouverez les définitions des noms d’assembly simples et complets à l’adresse https://go.microsoft.com/fwlink/?LinkId=64535.

Vous pouvez concevoir l'extracteur de faits avec la logique requise propre à l'application afin d'établir la connexion aux sources de données requises, de déclarer les données dans le moteur en tant que faits à long terme et de spécifier la logique pour actualiser ou déclarer dans le moteur de nouvelles instances des faits à long terme. Jusqu'à leur mise à jour, les valeurs initialement déclarées dans le moteur et donc mises en cache seront utilisées dans les cycles d'exécution ultérieurs. L’implémentation du récupérateur de faits retourne un objet qui est analogue à un jeton et peut être utilisé avec l’objet factsHandleIn pour déterminer s’il faut mettre à jour des faits existants ou affirmer de nouveaux faits. Lorsqu’une version de stratégie appelle son récupérateur de faits pour la première fois, l’objet factsHandleIn est toujours null, puis prend la valeur de l’objet retourné après l’exécution du récupérateur de faits.

Sachez que pour une même instance de moteur de règles, il n'est pas nécessaire de déclarer plusieurs fois un fait à long terme. Par exemple, lorsque vous utilisez la forme Règles d’appel dans une orchestration, la stratégie instance est déplacée dans un cache interne. Tous les faits à court terme sont alors retirés et les faits à long terme sont conservés. Si la même stratégie est appelée à nouveau, soit par la même instance d'orchestration, soit par une autre instance d'orchestration du même hôte, cette instance de stratégie est extraite du cache et réutilisée. Dans certains scénarios de traitement par lots, plusieurs instances de la même stratégie peuvent être créées. Si une nouvelle instance de stratégie est créée, vous devez vous assurer de déclarer les faits à long terme qui conviennent.

De plus, vous devrez écrire un code personnalisé pour implémenter les stratégies suivantes :

  • Savoir quand mettre à jour les faits à long terme

  • Suivi permettant de savoir quelle instance de moteur de règles utilise quels faits à long terme

    L'exemple de code suivant montre différentes implémentations d'extracteur de faits, qui sont associées à MyPolicy pour déclarer MyTableInstance en tant que fait à long terme, en utilisant divers types de liaisons.

Liaison DataTable

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;
      }
   }
}

Liaison 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;
      }
   }
}

L'exemple de code suivant montre comment déclarer les faits .NET et XML dans une implémentation d'extracteur de faits.

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;
      }
   }
}

Liaison 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;
      }
   }
}

Notez que les dataConnectiondoivent toujours être réaffirmés, lorsqu’ils sont fournis à partir d’un récupérateur de faits, comme indiqué dans l’exemple de code précédent. Le moteur instance utilise DataConnection pour interroger la base de données en fonction des conditions de règle, et toutes les lignes retournées par la requête sont déclarées dans la mémoire de travail du moteur en tant que TypedDataRow. La nouvelle actualisation de DataConnection garantit que les lignes d’une exécution précédente du moteur sont effacées de la mémoire.

En fait, il n’y a guère d’avantage à affirmer un DataConnection par le biais d’un récupérateur de faits, sauf qu’il offre un moyen d’externaliser la source de données.