From the comments you asked how doing this could be done with IParameterInspector. The operation name is part of the Before/AfterCall methods.
Just to add to my comments on which inspector to use. From Carlos Figueira's blogs:
The message inspectors, described in the previous post of this series,
allows you complete control over the message going through the WCF
stack. They’re very powerful, but you have to know how to deal with
the Message object, which is not the most desirable way of
programming. If the service model in WCF hides all the messaging
framework by allowing us to define our services in terms of
strongly-typed operations (i.e., using nice primitive and user defined
types), there should be a way of intercepting requests / responses
after all the processing to extract those parameters from incoming
messages (or before they’re packaged in outgoing messages) is done.
The IParameterInspector is exactly that – before and after each call,
the inspector gets a chance to inspect the operation inputs, outputs
and return value, in the same types as defined by the operation
contract, no conversion needed (the only thing needed is a cast, since
the parameters are passed as objects).
This is a complete command line program that demonstrates:
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();
}
}
}
}
It should give the output:
Calling operation:DoSomthing
Called:hi
Completed operation:DoSomthing
Press ENTER to close the host.