TransactionInterceptor.cs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. using System.Reflection;
  2. using System.Threading.Tasks;
  3. using Castle.DynamicProxy;
  4. using FreeSql;
  5. using Admin.Core.Common.Extensions;
  6. using Admin.Core.Common.Output;
  7. using Admin.Core.Common.Attributes;
  8. namespace Admin.Core.Aop
  9. {
  10. public class TransactionInterceptor : IInterceptor
  11. {
  12. IUnitOfWork _unitOfWork;
  13. private readonly UnitOfWorkManager _unitOfWorkManager;
  14. public TransactionInterceptor(UnitOfWorkManager unitOfWorkManager)
  15. {
  16. _unitOfWorkManager = unitOfWorkManager;
  17. }
  18. public void Intercept(IInvocation invocation)
  19. {
  20. var method = invocation.MethodInvocationTarget ?? invocation.Method;
  21. if (method.HasAttribute<TransactionAttribute>())
  22. {
  23. InterceptTransaction(invocation, method);
  24. }
  25. else
  26. {
  27. invocation.Proceed();
  28. }
  29. }
  30. private async void InterceptTransaction(IInvocation invocation, MethodInfo method)
  31. {
  32. try
  33. {
  34. var transaction = method.GetAttribute<TransactionAttribute>();
  35. _unitOfWork = _unitOfWorkManager.Begin(transaction.Propagation, transaction.IsolationLevel);
  36. invocation.Proceed();
  37. dynamic returnValue = invocation.ReturnValue;
  38. if (returnValue is Task)
  39. {
  40. returnValue = await returnValue;
  41. }
  42. if (returnValue is IResponseOutput res && !res.Success)
  43. {
  44. _unitOfWork.Rollback();
  45. }
  46. else
  47. {
  48. _unitOfWork.Commit();
  49. }
  50. }
  51. catch
  52. {
  53. _unitOfWork.Rollback();
  54. }
  55. finally
  56. {
  57. _unitOfWork.Dispose();
  58. }
  59. }
  60. }
  61. }