プリイベント ハンドラー クラスおよびポストイベント ハンドラー クラスの作成

完了

イベント ハンドラー クラスをプリハンドラーおよびポストハンドラーに使用すると、メソッド ラッピングにコマンド チェーン (CoC) を使用する方法など、アプリケーションを拡張できます。

イベント ハンドラー クラスはアプリケーションを拡張するもう 1 つの方法で、他のイベント ハンドラー クラスと同じ方法で使用します。 元のメソッドの前に実行されるプリハンドラーと、後で実装するポストハンドラーを元のメソッドが含むクラスで、プリハンドラーとポストハンドラーを使用できます。 ハンドラーは元のメソッドを囲みます。 また属性を使用して、プリハンドラーとポストハンドラーの拡張を防止、または許可できます。

プリイベント クラスおよびポストイベント クラス

プリイベント ハンドラー クラスおよびポストイベント ハンドラー クラスを追加するには、新しいイベント ハンドラー クラスを作成します。 プロジェクトを右クリックするかコンテキスト メニューを有効化し、追加新規項目コードクラス、またはクラスの追加を選択すると、ソリューション エクスプローラーからプロジェクトにクラスを追加できます。

CustTableTableEventHandler など、プリイベント クラスおよびポストイベント クラスの内容を示す名前を入力します。 CustTable はテーブルまたはフォームの場合があるので、CustTable などの開始点としてオブジェクト名を使用し、次に Table などのオブジェクト タイプを追加することをお勧めします。 そうすると、EventHandler を使用してそれを追加できます。 たとえば、CustTableTableEventHandlerCustTableFormEventHandler という名前の 2 つのイベント ハンドラー クラスを持つ場合があります。

プリイベントまたはポストイベントを追加するには、イベント ハンドラー クラス内のメソッドが検出可能であることを確認してください。 メソッドで、コンテキスト メニューを右クリックまたはアクティブ化した後、次の画像のようにイベント ハンドラー メソッドのコピーを選択し、プリイベント ハンドラーを選択します。

イベント ハンドラー メソッドをコピーして、プリイベント ハンドラーを選択する方法を示す Visual Studio のスクリーンショット。

プリイベント ハンドラーを選択した後、イベント ハンドラー クラスに移動し、メソッドを貼り付けます。 メソッドに戻り、ポストイベント ハンドラーを選択した後、それをイベント ハンドラー クラスに貼り付けます。

プリイベントおよびポストイベントに対する 2 つのメソッドが表示され、次のコード サンプルが示すように、これらの 2 つのメソッド (スーパー呼び出し) の間で元のメソッドが呼び出されます。

internal final class CustTableTableEventHandler
{
    /// <summary>
    ///
    /// </summary>
    /// <param name="args"></param>
    [PreHandlerFor(tableStr(CustTable), tableMethodStr(CustTable, insert))]
    public static void CustTable_Pre_delete(XppPrePostArgs args)
    {
        CustTable custTable = args.getThis() as CustTable;

        // do something
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="args"></param>
    [PostHandlerFor(tableStr(CustTable), tableMethodStr(CustTable, insert))]
    public static void CustTable_Post_delete(XppPrePostArgs args)
    {
        CustTable custTable = args.getThis() as CustTable;

        // do something
    }
}

属性

メソッドに属性を追加して、ユーザーがプリハンドラーやポストハンドラー、その他の拡張機能を使用できなくすることができます。 追加できる属性の 3 つのタイプは、hookable、wrappable、replaceable です。

hookable 属性は、次のアクションを実行します。

  • [Hookable(false)] - プリイベントやポストイベントを作成できない、つまりメソッドが wrappable ではないということで、動作を上書きします。
  • [Hookable(true)] - プリイベントおよびポストイベントを作成できるように、動作を上書きします。

wrappable 属性は、次のアクションを実行します。

  • [Wrappable(false)] - メソッドがラップできなくなるように、ラップ対象の (最終でない) パブリック メソッドおよび保護されたメソッドに対する既定の機能を上書きします。 つまり、このメソッドはラップ可能ではありません。
  • [Wrappable(true)] - メソッドをラップすることができるように、最終とマークされたメソッドをラップできないという動作を上書きします。 つまり、このメソッドはラップ可能になります。

replaceable 属性は、次のアクションを実行します。

  • [Replaceable (false)] - コマンド チェーン (CoC) に無条件の次の呼び出しが必ず含まれるように動作を上書きします。
  • [Replaceable (true)] CoC 拡張子を付けられるように動作を上書きしますが、無条件にを呼び出す必要はありません。

replaceable メソッドは、ラップ可能である必要もあります。

次のコード例では、[Hookable(false), Wrappable(false)] を使用して、メソッドがプリイベントおよびポストイベントおよび CoC を持つとして保護されている場合を示します。[Hookable(false), Wrappable(false)] は、機能を拡張できないという意味になります。

    /// <summary>
    /// Calculates and sets the <c>AmountCur</c> field using the <c>Quantity</c> and <c>UnitPrice</c>
    /// values.
    /// </summary>
    /// <param name="_qty">
    /// Item quantity on the line.
    /// </param>
    /// <returns>
    /// The <c>AmountCur</c> value.
    /// </returns>
    [Hookable(false), Wrappable(false)]
    public AmountCur calcLineAmount(Qty _qty = this.Quantity)
    {
        return this.salesPurchLineInterface().calcLineAmount(_qty);
    }

メソッドに属性を使用している場合は、機能拡張に注意し、潜在的に機能を損なう可能性があります。