IExtension を使用して、プロキシを使用しているクライアントからパラメーターを取得するクライアント側の動作を作成しました。そして、私のアプローチは機能しますが、より良い方法が必要です。
ここで、私が何をしようとしているのかを明確にするために、現在の作業アプローチの詳細を共有します。
プロキシを使用するクライアントは、次のようなパラメーターを提供します。
var client = new ServiceAlphaClient();
client.InnerChannel.Extensions.Add(new ParameterHolder("hello"));
client.DoSomething("some interesting service invocation");
client.Close();
IExtensionParameterHolder
は次のようになります。
public class ParameterHolder: IExtension<IContextChannel>
{
public string someParam;
public ParameterHolder(string someParam)
{
this.someParam = someParam;
}
#region IExtension required-but-useless stuff
public void Attach(IContextChannel owner)
{
}
public void Detach(IContextChannel owner)
{
}
#endregion
}
パラメータを使用するクライアント側の動作拡張は次のようになります。
#region IClientMessageInspector
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
//throw new NotImplementedException();
}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
ParameterHolder holder = channel.Extensions.Find<ParameterHolder>();
string param = holder.someParam;
request.Headers.Add(MessageHeader.CreateHeader(headerName, headerNamespace, someParam));
return null;
}
#endregion
上記のすべてについて私が気に入らない点:
- ClientMessageInspector 拡張機能は、送信要求ごとに Extensions.Find を繰り返し呼び出しています。それは不必要で非効率的です。
- 私のプロキシを使用しているクライアントは、作成された新しいプロキシごとにパラメータを提供する必要があります。
最初の問題に関しては、インスペクター拡張機能で、効率を高めるために値を保存してテストすることができましたが、このパラメーターを早い段階で一度だけ取得できるようにしたいと考えています。具体的には、IContractBehavior 自体が AddBindingParameters(...) または ApplyClientBehavior(...) のいずれかでパラメーターをフェッチできるようにしたいと考えています。しかし、そこからクライアント チャネルに到達する方法がわかりません。
2 つ目の問題については、Extensions.Add() を使用して各プロキシ インスタンスにパラメーターを設定したくありません。クライアントでパラメーターを静的に設定できたらいいのにと思いますが、どういうわけか動作拡張機能が戻ってきてフェッチします。部分クラスを活用して支援する方法がよくわかりません。
とにかくこれらの問題を解決するには?「メタパラメータ」を WCF プロキシに渡すための全体的なより良い方法はありますか?