カスタムの累積 Functoid を使用して、インスタンス メッセージ内で複数回発生する値の累積操作を実行します。
累積 Functoid を開発するときは、3 つの関数を実装する必要があります。 3 つの関数は、マップが累積を実行するために必要な初期化、累積、および取得アクションに対応します。 これらの関数について説明する前に、スレッド セーフについて話し合うことが重要です。
Thread-Safe 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 つの関数を実装する必要があります。 コンストラクターで呼び出して設定する必要がある関数とメソッドを次の表にまとめます。 すべての関数は文字列値を返します。
注
各関数に最適な名前を決定しますが、各関数には引数の数と型が指定されている必要があります。
関数の目的 | 論争 | 参照を設定するには | インライン スクリプトを設定するには |
---|---|---|---|
初期化 | int index | SetExternalFunctionName |
SetScriptBuffer における functionNumber = 0 |
累積 | int index、string val、string scope | SetExternalFunctionName2 |
SetScriptBuffer に functionNumber = 1 |
取得 | int index | SetExternalFunctionName3 |
SetScriptBuffer のパラメータ functionNumber = 2 |
初期化
初期化を使用すると、蓄積を実行するために使用するメカニズムを準備できます。 配列の初期化、1 つ以上の値のリセット、または必要に応じて他のリソースの読み込みを行うことができます。 文字列の戻り値は使用されません。
累積
ここで、Functoid に適した累積操作を実行します。 BizTalk Server は、次の 3 つのパラメーターを渡します。
索引 マップ インスタンスを表す整数値。 複数のマップ インスタンスが同時に実行されている可能性があります。
ヴァル。 累積する必要がある値を含む文字列。 文字列 Cumulate Functoid を記述しない限り、これは数値です。
範囲。 累積する要素または属性値を示す数値を含む文字列。 実際の値は実装によって決まります。
累積する値と無視する値を決定します。 たとえば、0 未満の値は無視しても、値が数値でない場合は例外をスローできます。 BaseFunctoid には、検証に役立つ 2 つの関数 (IsDate と IsNumeric) が用意されています。
注
インライン スクリプトで IsDate または IsNumeric を使用する場合は、 必ず RequiredGlobalHelperFunctions を設定して、関数をスクリプトで使用できるようにします。
文字列の戻り値は使用されません。
取得
BizTalk Server は、マップ内の Functoid 設定によって決定されたすべての値の反復処理を完了すると、累積値を要求します。 get 関数には、マップ インスタンスを表す整数値である 1 つの引数 ( Index
) があります。 関数では、インデックス値を使用して累積値を検索し、文字列として返す必要があります。
例
次の例は、累積乗算を実行するためのカスタム Functoid を作成する方法を示しています。 これは、3 つの文字列リソースと 16 x 16 ピクセルのビットマップ リソースを含むリソース ファイルに依存します。
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 の使用
カスタムインライン関数体の開発
カスタムファンクトイド (BizTalk Server サンプル)