カスタムの累積 Functoid の開発
カスタムの累積 Functoid を使用して、インスタンス メッセージ内で何度も発生する値の累積処理を行います。
累積 Functoid を開発する場合、3 つの関数を実装する必要があります。 3 つの関数とは、マップで累積を行う場合に必要となる、初期化操作、累積操作、および取得操作です。 これらの関数を検討する前に、スレッドの安全性を検討することが重要です。
スレッド セーフ Functoid の作成
この Functoid のコードは、ストレス条件下でマップの複数のインスタンスが同時に実行される場合があるので、スレッド セーフにする必要があります。 注意事項を次に示します。
静的状態は、スレッド セーフであることが必要です。
インスタンス状態は、必ずしもスレッド セーフである必要はありません。
高いストレス条件下で実行されることを考慮してデザインします。 可能な場合、ロックの取得は避けます。
可能な場合、同期の必要性を避けるようにします。
BizTalk Server では、単純なメカニズムを使用することによって、スレッド セーフの累積 Functoid を簡単に作成できます。 3 つのすべての関数は、最初のパラメーターが同じ (整数型のインデックス値) です。 BizTalk Server は、初期化関数を呼び出すとき、固有の数値をインデックス値に割り当てます。 この値は、次のコードに示すように、累積値を格納する配列用のインデックスとして使用できます。
private HashTable cumulativeArray = new HashTable();
…
// Initialization function
public string InitCumulativeMultiply(int index)
{
cumulativeArray[index] = 1.0;
return string.Empty;
}
この例では、ArrayList の代わりに HashTable が使用されています。 このため、初期化関数は、順番どおりのインデックス値で呼び出されない場合があります。
3 つの累積関数の実装
開発するカスタムの累積 Functoid ごとに、3 つの関数を実装する必要があります。 コンストラクターで呼び出して設定する関数とメソッドを次の表に示します。 すべての関数は文字列の値を返します。
Note
各関数に対して、わかりやすい名前を設定します。また、関数ごとに引数の数と種類を指定する必要があります。
関数の目的 | 引数 | 参照の設定 | インライン スクリプトの設定 |
---|---|---|---|
初期化 | int index | SetExternalFunctionName | SetScriptBuffer と functionNumber = 0 |
累積 | int index, string val, string scope | SetExternalFunctionName2 | = 1 の functionNumber SetScriptBuffer |
取得 | int index | SetExternalFunctionName3 | = 2 の functionNumber SetScriptBuffer |
初期化
初期化を行うと、累積の実行で使用するメカニズムを準備できます。 配列の初期化、1 つ以上の値の再設定、または必要に応じた他のリソースの読み込みを行うことができます。 文字列の戻り値は使用されません。
累積
この操作で、Functoid の累積処理を実行します。 BizTalk Server は次の 3 つのパラメーターを渡します。
Index : マップのインスタンスを表す整数型の値です。 複数のマップのインスタンスが同時に実行される場合があります。
Val : 累積する値を含む文字列です。 文字列の累積 Functoid を記述していない場合は、数値が使用されます。
範囲。 累積する要素または属性を示す数値を含む文字列です。 実際の値は、実装によって決まります。
累積する値および無視する値を決めます。 たとえば、0 未満ではない値を無視し、値が数値ではない場合に例外をスローできます。 BaseFunctoid には、検証に役立つ 2 つの関数 IsDate と IsNumeric が用意されています。
Note
インライン スクリプトで IsDate または IsNumeric を使用する場合は、 必ず RequiredGlobalHelperFunctions を設定して、関数をスクリプトで使用できるようにします。
文字列の戻り値は使用されません。
取得
マップの Functoid の設定によって定義された、すべての値の繰り返し処理が完了すると、BizTalk Server は、累積された値を要求します。 get 関数には、 Index
マップ インスタンスを表す整数値である 1 つの引数 があります。 関数では、インデックス値を使用して、累積された値を検索してから文字列として返します。
例
乗算の累積を行うカスタム Functoid の作成方法を次に示します。 ここでは、3 つの文字列リソースと 16x16 ピクセルのビットマップ リソースが格納されたリソース ファイルがあることを前提としています。
using System;
using Microsoft.BizTalk.BaseFunctoids;
using System.Reflection;
using System.Text;
using System.Collections;
using System.Globalization;
namespace Microsoft.Samples.BizTalk.CustomFunctoid
{
public class CumulativeMultiplyFunctoid : BaseFunctoid
{
private ArrayList myCumulativeArray = new ArrayList();
public CumulativeMultiplyFunctoid() : base()
{
//ID for this functoid
ID = 6001;
// Resource assembly must be ProjectName.ResourceName if building with VS.Net
SetupResourceAssembly("Microsoft.Samples.BizTalk.CustomFunctoid.CustomFunctoidResources", Assembly.GetExecutingAssembly());
// Pass the resource ID names for functoid name, tooltip
// description and the 16x16 bitmap for the Map palette
SetName("IDS_CUMULATIVEMULTIPLYFUNCTOID_NAME");
SetTooltip("IDS_CUMULATIVEMULTIPLYFUNCTOID_TOOLTIP");
SetDescription("IDS_CUMULATIVEMULTIPLYFUNCTOID_DESCRIPTION");
SetBitmap("IDB_CUMULATIVEMULTIPLYFUNCTOID_BITMAP");
// Put this string handling function under the Cumulative
// Functoid tab in the Visual Studio toolbox for functoids
Category = FunctoidCategory.Cumulative;
// 2 required parameters, no optional parameters
SetMinParams(1);
SetMaxParams(2);
// Functoid accepts three inputs
AddInputConnectionType(ConnectionType.AllExceptRecord);
AddInputConnectionType((~ConnectionType.FunctoidCount) & (~ConnectionType.FunctoidIndex) & (~ConnectionType.FunctoidIteration) & (~ConnectionType.FunctoidCumulative) & (~ConnectionType.FunctoidLooping) & (~ConnectionType.Record));
AddInputConnectionType(ConnectionType.AllExceptRecord);
// Set the output connection type
OutputConnectionType = ConnectionType.AllExceptRecord;
// Set the Initialize, Cumulative and Get functions
SetExternalFunctionName(GetType().Assembly.FullName, "Microsoft.Samples.BizTalk.CustomFunctoid.CumulativeMultiplyFunctoid", "InitCumulativeMultiply");
SetExternalFunctionName2("AddToCumulativeMultiply");
SetExternalFunctionName3("GetCumulativeMultiply");
}
// Initialization function
public string InitCumulativeMultiply(int index)
{
if (index >= 0)
{
if (index >= myCumulativeArray.Count)
{
myCumulativeArray.Add(1.0);
}
else
{
myCumulativeArray[index] = 1.0;
}
}
return "";
}
// Cumulative function
public string AddToCumulativeMultiply(int index, string val, string reserved)
{
if (index < 0 || index >= myCumulativeArray.Count)
{
return "";
}
if (IsNumeric(val))
{
double dval = Convert.ToDouble(val, CultureInfo.InvariantCulture);
myCumulativeArray[index] = (double)(myCumulativeArray[index]) * dval;
}
return myCumulativeArray[index].ToString();
}
// Get Function
public string GetCumulativeMultiply(int index)
{
if (index < 0 || index >= myCumulativeArray.Count)
{
return "";
}
return myCumulativeArray[index].ToString();
}
}
参照
BaseFunctoid の使用
インライン型のカスタム Functoid の開発
カスタム Functoid (BizTalk Server サンプル)