Method name from IOperationInvoker
c#, wcf
Solution
The `IOperationInvoker` itself won't give you the operation name, but in order to use a custom invoker you'd normally use an operation behavior. The behavior has access to the operation name, and that can be passed to your custom invoker:
public class ParameterTracerOperationBehavior : IOperationBehavior
{
// ...
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
var originalInvoker = dispatchOperation.Invoker;
var operationName = operationDescription.Name;
var newInvoker = new ParameterTracerInvoker(originalInvoker, operationName);
dispatchOperation.Invoker = newInvoker;
}
}
public class ParameterTracerInvoker
{
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
private readonly string operationName;
public ParameterTracerInvoker(IOperationInvoker oldInvoker, string operationName)
: base(oldInvoker)
{
this.operationName = operationName;
}
// ...
}
Problem
I recently read Programming WCF Services, Third Edition by Juval Lowy. I am leveraging his `ParameterTracerInvoker : GenericInvoker` shown below to trace log using NLOG. It works great except for one thing that I think might not be possible, which is fetching the `MethodName` being called. As you can see in the `PreInvoke` method, I am logging the inputs, but not the method name. Anyone know how the method name could be retrieved? ``` public abstract class GenericInvoker : IOperationInvoker { internal readonly IOperationInvoker _oldInvoker; public GenericInvoker(IOperationInvoker oldInvoker) { Debug.Assert(oldInvoker != null); _oldInvoker = oldInvoker; } public virtual object[] AllocateInputs() { return _oldInvoker.AllocateInputs(); } /// <summary> /// Exceptions here will abort the call /// </summary> /// <returns></returns> protected virtual void PreInvoke(object instance, object[] inputs) { } /// <summary> /// Always called, even if operation had an exception /// </summary> /// <returns></returns> protected virtual void PostInvoke(object instance, object returnedValue, object[] outputs, Exception exception) { } public object Invoke(object instance, object[] inputs, out object[] outputs) { PreInvoke(instance, inputs); object returnedValue = null; object[] outputParams = new object[] { }; Exception exception = null; try { returnedValue = _oldInvoker.Invoke(instance, inputs, out outputParams); outputs = outputParams; return returnedValue; } catch (Exception operationException) { exception = operationException; throw; } finally { PostInvoke(instance, returnedValue, outputParams, exception); } } public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state) { PreInvoke(instance, inputs); return _oldInvoker.InvokeBegin(instance, inputs, callback, state); } public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result) { object returnedValue = null; object[] outputParams = { }; Exception exception = null; try { returnedValue = _oldInvoker.InvokeEnd(instance, out outputs, result); outputs = outputParams; return returnedValue; } catch (Exception operationException) { exception = operationException; throw; } finally { PostInvoke(instance, returnedValue, outputParams, exception); } } public bool IsSynchronous { get { return _oldInvoker.IsSynchronous; } } } public class ParameterTracerInvoker : GenericInvoker { private readonly Logger _logger = LogManager.GetCurrentClassLogger(); public ParameterTracerInvoker(IOperationInvoker oldInvoker) : base(oldInvoker) { } protected override void PreInvoke(object instance, object[] inputs) { //_logger.Trace(((SyncMethodInvoker)_oldInvoker).MethodName); _logger.Trace("Input Parameters:"); foreach (object argument in inputs) { if (argument != null) { _logger.Trace(argument.ToString()); } else { _logger.Trace("null"); } } } protected override void PostInvoke(object instance, object returnedValue, object[] outputs, Exception exception) { foreach (object output in outputs) { _logger.Trace("Output Parameters:"); _logger.Trace(output.ToString()); } returnedValue = "aaaaaaaaaaaa"; _logger.Trace("Returned: " + returnedValue ?? String.Empty); } } ```