IParameterInspectorでこれを行う方法を尋ねたコメントから。操作名は、Before/AfterCall メソッドの一部です。
どのインスペクターを使用するかについての私のコメントに追加するだけです。Carlos Figueira のブログから:
このシリーズの前回の投稿で説明したメッセージ インスペクターを使用すると、WCF スタックを通過するメッセージを完全に制御できます。これらは非常に強力ですが、Message オブジェクトの処理方法を知っておく必要があり、これは最も望ましいプログラミング方法ではありません。WCF のサービス モデルが、厳密に型指定された操作 (つまり、Nice プリミティブ型とユーザー定義型を使用) の観点からサービスを定義できるようにすることで、すべてのメッセージング フレームワークを隠している場合、要求/応答をインターセプトする方法が必要です。これらのパラメーターを受信メッセージから (または送信メッセージにパッケージ化される前に) 抽出する処理が行われます。IParameterInspector はまさにそれです。各呼び出しの前後に、インスペクターは操作の入力、出力、および戻り値を検査する機会を得ます。
これは、次のことを示す完全なコマンド ライン プログラムです。
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
namespace WCFClientInspector
{
public class OperationLogger : IParameterInspector
{
public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
{
Console.WriteLine("Completed operation:" + operationName);
}
public object BeforeCall(string operationName, object[] inputs)
{
Console.WriteLine("Calling operation:" + operationName);
return null;
}
}
public class OperationLoggerEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
foreach (ClientOperation operation in clientRuntime.ClientOperations)
{
operation.ClientParameterInspectors.Add(new OperationLogger());
}
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
[ServiceContract]
public interface ISimple
{
[OperationContract]
void DoSomthing(string s);
}
public class SimpleService : ISimple
{
public void DoSomthing(string s)
{
Console.WriteLine("Called:" + s);
}
}
public static class AttributesAndContext
{
static void Main(string[] args)
{
ServiceHost simpleHost = new ServiceHost(typeof(SimpleService), new Uri("http://localhost/Simple"));
simpleHost.Open();
ChannelFactory<ISimple> factory = new ChannelFactory<ISimple>(simpleHost.Description.Endpoints[0]);
factory.Endpoint.EndpointBehaviors.Add(new OperationLoggerEndpointBehavior());
ISimple proxy = factory.CreateChannel();
proxy.DoSomthing("hi");
Console.WriteLine("Press ENTER to close the host.");
Console.ReadLine();
((ICommunicationObject)proxy).Shutdown();
simpleHost.Shutdown();
}
}
public static class Extensions
{
static public void Shutdown(this ICommunicationObject obj)
{
try
{
obj.Close();
}
catch (Exception ex)
{
Console.WriteLine("Shutdown exception: {0}", ex.Message);
obj.Abort();
}
}
}
}
出力が得られるはずです:
Calling operation:DoSomthing
Called:hi
Completed operation:DoSomthing
Press ENTER to close the host.