Cómo crear un administrador de almacenes de datos
Un administrador de almacenes de datos es un componente que se utiliza para imponer instancias de hechos a largo plazo en una directiva durante su ejecución. Puede implementar la interfaz IFactRetriever y configurar una versión de directiva para usar esta implementación en tiempo de ejecución para incorporar las instancias de hechos a largo plazo. La versión de la directiva invoca el método UpdateFacts de la implementación del recuperador de hechos en cada ciclo de ejecución, si un recuperador de hechos está configurado para esa versión determinada.
Opcionalmente, puede implementar la interfaz IFactRemover en un componente de recuperación de hechos. El motor de reglas invoca el método UpdateFactsAfterExecution de la interfaz IFactRemover cuando se elimina la directiva. Esto le ofrece la oportunidad de realizar cualquier trabajo posterior a la ejecución, como confirmar cambios en la base de datos o retirar instancias de objetos de la memoria de trabajo del motor de reglas.
Para especificar un administrador de almacenes de datos para una directiva
Puede utilizar el siguiente código para configurar la regla establecida para utilizar una clase denominada "Retriever" en el ensamblado denominado "MyAssembly" como el administrador de almacenes de datos.
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;
Nota
Si especifica un nombre de ensamblado simple como MyAssembly como el primer parámetro para el constructor RuleEngineComponentConfiguration, el motor de reglas de BizTalk supone que es un ensamblado privado y busca el ensamblado en su carpeta de aplicación. Si especifica el nombre completo del ensamblado, como MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a310908b42c024fe, el motor de reglas asume que es un ensamblado compartido y busca el ensamblado en la caché global de ensamblados (GAC). Puede encontrar las definiciones de nombres de ensamblado simples y completos en https://go.microsoft.com/fwlink/?LinkId=64535.
Puede diseñar el administrador de almacenes de datos con la lógica específica de la aplicación requerida para conectar con los orígenes de datos necesarios, imponer los datos como hechos a largo plazo en el motor y especificar la lógica para actualizar o imponer nuevas instancias de los hechos a largo plazo en el motor. Hasta que no estén actualizados, los valores que se imponen inicialmente en el motor y, por consiguiente, se guardan en caché, se utilizarán en ciclos de ejecución posteriores. La implementación del recuperador de hechos devuelve un objeto que es análogo a un token y se puede usar junto con el objeto factsHandleIn para determinar si se deben actualizar los hechos existentes o declarar nuevos hechos. Cuando una versión de directiva llama a su recuperador de hechos por primera vez, el objeto factsHandleIn siempre es null y, a continuación, toma el valor del objeto devuelto después de la ejecución del recuperador de hechos.
Observe que para la misma instancia de motor de reglas, un hecho a largo plazo solo necesita imponerse una vez. Por ejemplo, cuando se usa la forma Reglas de llamada en una orquestación, la instancia de directiva se mueve a una caché interna. En ese momento, todos los hechos a corto plazo se retraen y los hechos a largo plazo se mantienen. Si vuelve a llamarse a la misma directiva, ya sea mediante la misma instancia de orquestación o mediante una diferente del mismo host, esa instancia de directiva se recupera de la caché y vuelve a utilizarse. En algunos escenarios de proceso por lotes, pueden crearse varias instancias de la misma directiva. Si se crea una nueva instancia de directiva, debe asegurarse de que se han impuesto los hechos a largo plazo correctos.
Además, quizá necesite escribir código personalizado para implementar las siguientes estrategias:
Saber cuándo actualizar los hechos a largo plazo
Realizar un seguimiento para saber qué instancia de motor de reglas utiliza qué hechos a largo plazo
En el siguiente código de ejemplo se muestran diversas implementaciones de administrador de almacenes de datos, que están asociadas con MyPolicy para imponer MyTableInstance como un hecho a largo plazo, mediante tipos de enlace diferentes.
Enlace de 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;
}
}
}
Enlace 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;
}
}
}
En el siguiente código de ejemplo se muestra cómo imponer hechos .NET y XML en una implementación de administrador de almacenes de datos.
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;
}
}
}
Enlace 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;
}
}
}
Tenga en cuenta que dataConnections siempre se debe volver a afirmar, cuando se proporciona a partir de un recuperador de hechos, como se muestra en el ejemplo de código anterior. La instancia del motor usa DataConnection para consultar la base de datos en función de las condiciones de regla y las filas devueltas por la consulta se declararían en la memoria de trabajo del motor como TypedDataRow. Al restablecer DataConnection, se garantiza que las filas de una ejecución anterior del motor se borren de la memoria.
De hecho, hay poca ventaja para afirmar un dataConnection a través de un recuperador de hechos, salvo que proporciona una manera de externalizar el origen de datos.