ファクト取得コンポーネントを作成する方法
ファクト取得コンポーネントは、ポリシーの実行時に、長期間のファクトのインスタンスをポリシーにアサートするために使用されるコンポーネントです。 IFactRetriever インターフェイスを実装し、実行時にこの実装を使用して長期的なファクト インスタンスを取り込むポリシー バージョンを構成できます。 ポリシー バージョンでは、ファクト レトリーバーが特定のバージョンに対して構成されている場合、すべての実行サイクルでファクトレトリーバー実装の UpdateFacts メソッドが呼び出されます。
必要に応じて、ファクト レトリーバー コンポーネントに IFactRemover インターフェイスを実装できます。 ルール エンジンは、ポリシーが破棄されると、IFactRemover インターフェイスの UpdateFactsAfterExecution メソッドを呼び出します。 これにより、データベースの変更をコミットしたり、ルール エンジンの作業メモリからオブジェクト インスタンスを取り消したりするなど、実行後の作業を行うことができます。
ポリシーに対してファクト取得コンポーネントを指定するには
ファクト取得コンポーネントとして、"MyAssembly" アセンブリの "Retriever" というクラスを使用するようにルール セットを構成するには、次のようなコードを使用します。
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;
Note
RuleEngineComponentConfiguration コンストラクターの最初のパラメーターとして MyAssembly のような単純なアセンブリ名を指定した場合、BizTalk ルール エンジンではプライベート アセンブリと認識され、ユーザーのアプリケーション フォルダー内のアセンブリが検索されます。 MyAssembly、Version=1.0.0.0、Culture=neutral、PublicKeyToken=a310908b42c024fe などの完全修飾アセンブリ名を指定すると、ルール エンジンは共有アセンブリであると見なし、グローバル アセンブリ キャッシュ (GAC) 内のアセンブリを検索します。 単純なアセンブリ名と完全修飾アセンブリ名の定義は、 にあります https://go.microsoft.com/fwlink/?LinkId=64535。
特定のデータ ソースに接続するためのアプリケーション固有のロジックを備えたファクト取得コンポーネントを設計し、そのデータをエンジンに対する長期間のファクトとしてアサートして、新しいファクトのインスタンスをエンジンに対して更新またはアサートするためのロジックを指定できます。 後続の実行サイクルでは、値が更新されるまで、最初にエンジンに対してアサートされ、キャッシュされた値が使用されます。 ファクト レトリーバーの実装は、トークンに似た オブジェクトを返し、 factsHandleIn オブジェクトと共に使用して、既存のファクトを更新するか、新しいファクトをアサートするかを決定できます。 ポリシー バージョンがファクト レトリバーを初めて呼び出すと、 factsHandleIn オブジェクトは常に null になり、ファクト レトリーバーの実行後に戻りオブジェクトの値を受け取ります。
長期間のファクトをアサートするのは、同じルール エンジンのインスタンスに対して 1 回だけでかまいません。 たとえば、オーケストレーションで [ルールの呼び出し ] 図形を使用すると、ポリシー インスタンスは内部キャッシュに移動されます。 このとき、短期間のファクトはすべて取り消され、長期間のファクトが維持されます。 同じオーケストレーション インスタンスまたは同じホストの別のオーケストレーション インスタンスによって同じポリシーが再び呼び出された場合、このポリシー インスタンスがキャッシュから取得され再利用されます。 バッチ処理のシナリオによっては、同じポリシーのインスタンスが複数作成される場合があります。 新しいポリシー インスタンスが作成された場合は、適切な長期間のファクトがアサートされるように配慮する必要があります。
また、次のような処理を実現するカスタム コードを作成することもできます。
長期間のファクトが更新されたタイミングを確認する。
どのルール エンジンのインスタンスが、どの長期間のファクトによって使用されたかを追跡する。
次のコード例は、ファクト取得コンポーネントの実装例です。ファクト取得コンポーネントを MyPolicy に関連付け、各種のバインディング方法を使って MyTableInstance を長期間のファクトとしてアサートします。
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;
}
}
}
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;
}
}
}
次のコード例は、ファクト取得コンポーネントを実装することにより、.NET および XML のファクトをアサートする方法を示しています。
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;
}
}
}
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;
}
}
}
前のコード サンプルに示すように、ファクト レトリーバーから提供された場合は、 DataConnections を常に再アサートする必要があることに注意してください。 エンジン インスタンスは DataConnection を使用して、ルールの条件に基づいてデータベースにクエリを実行します。クエリによって返されるすべての行は、 TypedDataRowとしてエンジンの作業メモリにアサートされます。 DataConnection を再アサートすることにより、前回のエンジンの実行によって返された行が確実にメモリからクリアされます。
実際、データ ソースを外部化する方法を提供する点を除き、ファクト レトリーバーを介して DataConnection をアサートする利点はほとんどありません。