forked from anjoy8/Blog.Core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBlogTranAOP.cs
More file actions
139 lines (124 loc) · 4.28 KB
/
BlogTranAOP.cs
File metadata and controls
139 lines (124 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
using Blog.Core.Common;
using Castle.DynamicProxy;
using Microsoft.Extensions.Logging;
using System;
using System.Reflection;
using System.Threading.Tasks;
using Blog.Core.Common.DB;
using Blog.Core.Repository.UnitOfWorks;
namespace Blog.Core.AOP
{
/// <summary>
/// 事务拦截器BlogTranAOP 继承IInterceptor接口
/// </summary>
public class BlogTranAOP : IInterceptor
{
private readonly ILogger<BlogTranAOP> _logger;
private readonly IUnitOfWorkManage _unitOfWorkManage;
public BlogTranAOP(IUnitOfWorkManage unitOfWorkManage, ILogger<BlogTranAOP> logger)
{
_unitOfWorkManage = unitOfWorkManage;
_logger = logger;
}
/// <summary>
/// 实例化IInterceptor唯一方法
/// </summary>
/// <param name="invocation">包含被拦截方法的信息</param>
public void Intercept(IInvocation invocation)
{
var method = invocation.MethodInvocationTarget ?? invocation.Method;
//对当前方法的特性验证
//如果需要验证
if (method.GetCustomAttribute<UseTranAttribute>(true) is { } uta)
{
try
{
Before(method, uta.Propagation);
invocation.Proceed();
// 异步获取异常,先执行
if (IsAsyncMethod(invocation.Method))
{
var result = invocation.ReturnValue;
if (result is Task)
{
Task.WaitAll(result as Task);
}
}
After(method);
}
catch (Exception ex)
{
_logger.LogError(ex.ToString());
AfterException(method);
throw;
}
}
else
{
invocation.Proceed(); //直接执行被拦截方法
}
}
private void Before(MethodInfo method, Propagation propagation)
{
switch (propagation)
{
case Propagation.Required:
if (_unitOfWorkManage.TranCount <= 0)
{
_logger.LogDebug($"Begin Transaction");
Console.WriteLine($"Begin Transaction");
_unitOfWorkManage.BeginTran(method);
}
break;
case Propagation.Mandatory:
if (_unitOfWorkManage.TranCount <= 0)
{
throw new Exception("事务传播机制为:[Mandatory],当前不存在事务");
}
break;
case Propagation.Nested:
_logger.LogDebug($"Begin Transaction");
Console.WriteLine($"Begin Transaction");
_unitOfWorkManage.BeginTran(method);
break;
default:
throw new ArgumentOutOfRangeException(nameof(propagation), propagation, null);
}
}
private void After(MethodInfo method)
{
_unitOfWorkManage.CommitTran(method);
}
private void AfterException(MethodInfo method)
{
_unitOfWorkManage.RollbackTran(method);
}
/// <summary>
/// 获取变量的默认值
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public object GetDefaultValue(Type type)
{
return type.IsValueType ? Activator.CreateInstance(type) : null;
}
private async Task SuccessAction(IInvocation invocation)
{
await Task.Run(() =>
{
//...
});
}
public static bool IsAsyncMethod(MethodInfo method)
{
return (
method.ReturnType == typeof(Task) ||
(method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>))
);
}
private async Task TestActionAsync(IInvocation invocation)
{
await Task.Run(null);
}
}
}