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