カスタム フィルターを使用すると、システム提供のメッセージ フィルターを使用して実現できない一致ロジックを定義できます。 たとえば、特定のメッセージ要素をハッシュし、その値を調べて、フィルターが true または false を返す必要があるかどうかを判断するカスタム フィルターを作成できます。
実装
カスタム フィルターは、 MessageFilter 抽象基本クラスの実装です。 カスタム フィルターを実装する場合、コンストラクターは必要に応じて 1 つの文字列パラメーターを受け取ることができます。 このパラメーターには、一致を実行するためにフィルターが実行時に必要とする値または構成を提供するために MessageFilter コンストラクターに渡される構成情報が含まれます。 たとえば、これを使用して、評価対象のメッセージ内でフィルターが検索する値を指定できます。 次の例は、文字列パラメーターを受け取るカスタム メッセージ フィルターの基本的な実装を示しています。
public class MyMessageFilter: MessageFilter
{
string filterData;
public MyMessageFilter(string filterData)
{
if(string.IsNullOrEmpty(filterData)
throw new ArgumentNullException("filterData");
this.filterData=filterData;
}
public override bool Match(System.ServiceModel.Channels.Message message)
{
...
return retValue;
}
public override bool Match(System.ServiceModel.Channels.MessageBuffer buffer)
{
...
return retValue;
}
}
注
実際の実装では、Match メソッドには、メッセージを調べて、このメッセージ フィルターが true または false を返す必要があるかどうかを判断するロジックが含まれています。
[パフォーマンス]
カスタム フィルターを実装する場合は、フィルターがメッセージの評価を完了するために必要な最大時間を考慮することが重要です。 メッセージは一致が見つかる前に複数のフィルターに対して評価される可能性があるため、すべてのフィルターを評価する前にクライアント要求がタイムアウトしないようにすることが重要です。 そのため、カスタム フィルターには、メッセージの内容または属性を評価してフィルター条件に一致するかどうかを判断するために必要なコードのみが含まれている必要があります。
一般に、カスタム フィルターを実装する場合は、以下を避ける必要があります。
IO (ディスクまたはデータベースへのデータの保存など)。
ドキュメント内の複数のレコードをループするなどの不要な処理。
共有リソースのロックの取得やデータベースに対する参照の実行を伴う呼び出しなどのブロック操作。
運用環境でカスタム フィルターを使用する前に、パフォーマンス テストを実行して、フィルターがメッセージを評価するのにかかる平均時間を決定する必要があります。 フィルター テーブルで使用される他のフィルターの平均処理時間と組み合わせると、クライアント アプリケーションで指定する必要がある最大タイムアウト値を正確に判断できます。
使用方法
ルーティング サービスでカスタム フィルターを使用するには、"Custom" 型の新しいフィルター エントリ、メッセージ フィルターの完全修飾型名、およびアセンブリの名前を指定して、フィルター テーブルに追加する必要があります。 他の MessageFilter と同様に、カスタム フィルターのコンストラクターに渡される文字列 filterData を指定できます。
次の例は、ルーティング サービスでカスタム フィルターを使用する方法を示しています。
<!--ROUTING SECTION -->
<routing>
<filters>
<filter name="CustomFilter1" filterType="Custom"
customType="CustomAssembly.MyMessageFilter,
CustomAssembly" filterData="custom data" />
</filters>
<filterTables>
<table name="routingTable1">
<filters>
<add filterName="CustomFilter1" endpointName="CalculatorService" />
</filters>
</table>
</filterTables>
</routing>
RoutingConfiguration rc = new RoutingConfiguration();
List<ServiceEndpoint> endpointList = new List<ServiceEndpoint>();
endpointList.Add(client);
rc.FilterTable.Add(new MyMessageFilter("CustomData"), endpointList);