InterfaceInterceptorBase.cs 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using Unity.Interception.InterceptionBehaviors;
  6. using Unity.Interception.PolicyInjection.Pipeline;
  7. using VCommon.Diagnostics;
  8. namespace VCommon.Ioc
  9. {
  10. public abstract class InterfaceInterceptorBase : IInterceptionBehavior
  11. {
  12. public virtual bool WillExecute => true;
  13. public virtual IEnumerable<Type> GetRequiredInterfaces() => Array.Empty<Type>();
  14. public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
  15. {
  16. long msUsed = 0;
  17. var begin = DateTime.Now;
  18. var svcClass = input.Target.GetType();
  19. var svcMethod = input.MethodBase;
  20. IReadOnlyDictionary<string, object> paramDic = Enumerable.Range(0, input.Arguments.Count).ToDictionary(p => input.Arguments.ParameterName(p), p => input.Arguments[p]);
  21. BeforeInvoke(begin, svcClass, svcMethod, paramDic);
  22. IMethodReturn result;
  23. using (new TimingMeasureAction(p => msUsed = p)) result = getNext()(input, getNext);
  24. AfterInvoke(begin, msUsed, svcClass, svcMethod, paramDic, result.ReturnValue, result.Exception);
  25. return result;
  26. }
  27. protected abstract void BeforeInvoke(DateTime time, Type svcClass, MethodBase svcMethod, IReadOnlyDictionary<string, object> paramDic);
  28. protected abstract void AfterInvoke(DateTime time, long msUsed, Type svcClass, MethodBase svcMethod, IReadOnlyDictionary<string, object> paramDic, object returnValue, Exception exception);
  29. }
  30. }