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)
浙公网安备 33010602011771号