.netwcfwcf-extensions

WCF extension for logging and performing actions for each method. IErrorHandler has no notion of method?


I have normal WCF service with few methods.

I would like to log some information and perform some actions at the beginning of method and in the end.

By implementing IParameterInspector I can easily do lot of logging. Methods BeforeCall and AfterCall give me almost everything I need.

But it doesn't work for exceptions. There is IErrorHandler, which allows me to perform some handling if exception happened. Drawback is that I don't know from which method it was thrown. All because IErrorHandler is attached to service behavior, not to operation itself.

However, I can get method name using code below:

((System.Reflection.RuntimeMethodInfo)(exception.TargetSite)).Name == "MyMethod"

This doesn't look like good idea for me.

Question: Guys, are there any other WCF extensions I can use to achieve my goal? Would you recommend to use old buddy try-catch, and maybe wrap it into some nice syntax so I can perform actions at the beginning and in the end? What would be the syntax? What do you use for similar purposes?

Thanks ahead.


Solution

  • How about an IOperationInvoker?

    public class NHibernateOperationInvoker : IOperationInvoker {
        private readonly IOperationInvoker _invoker;
        private readonly String _operationName;
    
        public NHibernateOperationInvoker(IOperationInvoker invoker, String operationName) {
            _invoker = invoker;
            _operationName = operationName;
        }
    
        public Object[] AllocateInputs() {
            return _invoker.AllocateInputs();
        }
    
        public Object Invoke(Object instance, Object[] inputs, out Object[] outputs) {
            using (var context = NHibernateContext.CreateNew()) {
                try {
                    var result = _invoker.Invoke(instance, inputs, out outputs);
                    context.Commit();
                    return result;
                } catch(Exception ex) {
                    Debug.Fail("Operation " + _operationName + " failed with " + ex.Message);
                }
            }
        }
    
        public IAsyncResult InvokeBegin(Object instance, Object[] inputs, AsyncCallback callback, Object state) {
            throw new NotImplementedException("NHibernateOperationInvoker.InvokeBegin");
        }
    
        public Object InvokeEnd(Object instance, out Object[] outputs, IAsyncResult result) {
            throw new NotImplementedException("NHibernateOperationInvoker.InvokeEnd");
        }
    
        public Boolean IsSynchronous {
            get { return true; }
        }
    }
    

    This is attached using an IOperationBehavior which does dispatchOperation.Invoker = new NHibernateOperationInvoker(dispatchOperation.Invoker, dispatchOperation.Name);