WCF自定义Attribute记录日志或异常

来源:互联网 发布:linux字体 编辑:程序博客网 时间:2024/06/14 03:29

1、定义一个attribute,同时继承接口 IOperationBehavior

[AttributeUsage(AttributeTargets.Method)]    public class RecordAttribute : Attribute, IOperationBehavior    {        private readonly string _operationName;        private readonly RecordType _recordType;        public RecordAttribute(string methodname, RecordType recordType)        {            _operationName = methodname;            _recordType = recordType;        }        protected RecordInvoker CreateInvoker(IOperationInvoker oldInvoker)        {            return new RecordInvoker(oldInvoker, _operationName, _recordType);        }        public void Validate(OperationDescription operationDescription)        {        }        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)        {            IOperationInvoker oldInvoker = dispatchOperation.Invoker;            dispatchOperation.Invoker = CreateInvoker(oldInvoker);        }        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)        {        }        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)        {        }    }

2. 定义RecordInvoker ,继承IOperationInvoker

    public class RecordInvoker : IOperationInvoker    {        private readonly IOperationInvoker _mOldInvoker;        private readonly string _operationName;        private readonly RecordType _recordType;        protected void PreInvoke(object instance, object[] inputs)        {            if (_recordType == RecordType.Log || _recordType == RecordType.LogAndException)            {                //记录日志            }        }        protected void PostInvoke(object instance, object returnedValue, object[] outputs, Exception err)        {            if (err != null && (_recordType == RecordType.Exception || _recordType == RecordType.LogAndException))    //如果有异常            {                //记录异常            }        }        public RecordInvoker(IOperationInvoker oldInvoker, string operationName, RecordType recordType)        {            _mOldInvoker = oldInvoker;            _operationName = operationName;            _recordType = recordType;        }        public object[] AllocateInputs()        {            return _mOldInvoker.AllocateInputs();        }        public object Invoke(object instance, object[] inputs, out object[] outputs)        {            PreInvoke(instance, inputs);            object returnedValue = null;            var outputParams = new object[] { };            Exception exception = null;            try            {                returnedValue = _mOldInvoker.Invoke(instance, inputs, out outputParams);                outputs = outputParams;                return returnedValue;            }            catch (Exception err)            {                outputs = null;                exception = err;                return null;            }            finally            {                PostInvoke(instance, returnedValue, outputParams, exception);            }        }        public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)        {            PreInvoke(instance, inputs);            return _mOldInvoker.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 = _mOldInvoker.InvokeEnd(instance, out outputs, result);                outputs = outputParams;                return returnedValue;            }            catch (Exception err)            {                outputs = null;                exception = err;                return null;            }            finally            {                PostInvoke(instance, returnedValue, outputParams, exception);            }        }        public bool IsSynchronous        {            get            {                return _mOldInvoker.IsSynchronous;            }        }    }

3、enum RecordType 定义如下

    public enum RecordType    {        None = 1,        /// <summary>        /// 记录日志        /// </summary>        Log = 2,        /// <summary>        /// 记录异常        /// </summary>        Exception = 3,        /// <summary>        /// 记录日志和异常        /// </summary>        LogAndException = 4    }

4、在需要记录日志的方法上加上自定义的特性:

[Record("Seo.CompanyService.GetCompanyWithCity", RecordType.Exception)]
        public IList<Company> GetCompanyWithCity(long cityId)