1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
private
static
void
SayHello(
string
user,
string
title)
{
Console.WriteLine(
string
.Format(
"Hello {0} {1}"
, title, user));
}
private
static
void
ThrowException()
{
throw
new
Exception(
"I'm a test message."
);
}
static
void
Main(
string
[] args)
{
SayHello(
"Richie"
,
"Mr."
);
try
{
ThrowException();
}
catch
{
}
Console.ReadKey();
return
;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
[Serializable]
public
class
OnMyExceptionAspect : OnMethodBoundaryAspect
{
public
override
void
OnEntry(MethodExecutionEventArgs eventArgs)
{
base
.OnEntry(eventArgs);
Console.WriteLine(
string
.Format(
"Entering method: {0}"
, eventArgs.Method.Name));
object
[] arguments = eventArgs.GetReadOnlyArgumentArray();
ParameterInfo[] parameters = eventArgs.Method.GetParameters();
for
(
int
i = 0; arguments !=
null
&& i < arguments.Length; i++)
Console.WriteLine(
string
.Format(
" arg{0} {1}: {2}"
, i + 1, parameters[i].Name, arguments[i]));
}
public
override
void
OnExit(MethodExecutionEventArgs eventArgs)
{
base
.OnExit(eventArgs);
Console.WriteLine(
string
.Format(
"Exiting method: {0}"
, eventArgs.Method.Name));
}
public
override
void
OnException(MethodExecutionEventArgs eventArgs)
{
Console.WriteLine(
"There's an error occured:"
+ eventArgs.Exception.Message);
base
.OnException(eventArgs);
}
}
|
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
|
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method)]
public
class
PropertyChangedNotificationAttribute : OnMethodBoundaryAspect
{
private
object
_preValue;
public
override
void
OnExit(MethodExecutionEventArgs eventArgs)
{
base
.OnExit(eventArgs);
if
(!eventArgs.Method.IsSpecialName)
return
;
if
(!eventArgs.Method.Name.StartsWith(
"get_"
)
&& !eventArgs.Method.Name.StartsWith(
"set_"
))
return
;
bool
isSetter = eventArgs.Method.Name.StartsWith(
"set_"
);
string
property = eventArgs.Method.Name.Substring(4);
if
(isSetter)
Console.WriteLine(
string
.Format(
"Property \"{0}\" was changed from \"{1}\" to \"{2}\"."
, property
,
this
._preValue
,
this
.GetPropertyValue(eventArgs.Instance, property)));
else
Console.WriteLine(
string
.Format(
"Property \"{0}\" was read."
, property));
}
public
override
void
OnEntry(MethodExecutionEventArgs eventArgs)
{
base
.OnEntry(eventArgs);
//记录属性更改前的值
if
(!eventArgs.Method.IsSpecialName)
return
;
if
(!eventArgs.Method.Name.StartsWith(
"set_"
))
return
;
string
property = eventArgs.Method.Name.Substring(4);
this
._preValue =
this
.GetPropertyValue(eventArgs.Instance, property);
}
private
object
GetPropertyValue(
object
instance,
string
property)
{
PropertyInfo getter = instance.GetType().GetProperty(property);
return
getter.GetValue(instance,
null
);
}
}
|
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
|
[PropertyChangedNotification]
public
class
Person
{
private
string
firstName;
private
string
lastName;
public
Person(
string
first,
string
last)
{
this
.firstName = first;
this
.lastName = last;
}
public
string
FirstName
{
get
{
return
firstName; }
set
{ firstName = value; }
}
public
string
LastName
{
get
{
return
lastName; }
set
{ lastName = value; }
}
public
string
Name
{
get
{
return
this
.FirstName +
" "
+
this
.LastName; }
}
}
<BR>
static
void
Main(
string
[] args)
{
Person user =
new
Person(
"Richie"
,
"Liu"
);
user.FirstName =
"RicCC"
;
Console.WriteLine(
string
.Format(
"{{ {0} {1} }}"
, user.FirstName, user.LastName));
Console.ReadKey();
}
|
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
|
[Serializable]
public
sealed
class
CacheAttribute : OnMethodBoundaryAspect
{
// 用来生成缓存的key值,key值中包含方法名、参数值等,因此参数不一时方法会被执行
private
MethodFormatStrings formatStrings;
// 用于缓存
private
static
readonly
Dictionary<STRING,
object
=
""
> cache =
new
Dictionary<STRING,
object
=
""
>();
<BR>
// 编译时刻执行的方法
// Cache这个attribute用于方法上,某些方法不允许使用缓存,将在下面进行检查
public
override
bool
CompileTimeValidate(MethodBase method)
{
// Don't apply to constructors.
if
(method
is
ConstructorInfo)
{
Message.Write(SeverityType.Error,
"CX0001"
,
"Cannot cache constructors."
);
return
false
;
}
MethodInfo methodInfo = (MethodInfo)method;
// Don't apply to void methods.
if
(methodInfo.ReturnType.Name ==
"Void"
)
{
Message.Write(SeverityType.Error,
"CX0002"
,
"Cannot cache void methods."
);
return
false
;
}
// Does not support out parameters.
ParameterInfo[] parameters = method.GetParameters();
for
(
int
i = 0; i < parameters.Length; i++)
{
if
(parameters[i].IsOut)
{
Message.Write(SeverityType.Error,
"CX0003"
,
"Cannot cache methods with return values."
);
return
false
;
}
}
return
true
;
}
// 编译时刻执行的方法
public
override
void
CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
this
.formatStrings = Formatter.GetMethodFormatStrings(method);
}
<BR>
public
override
void
OnEntry(MethodExecutionArgs eventArgs)
{
//生成缓存的key值
string
key =
this
.formatStrings.Format(
eventArgs.Instance, eventArgs.Method, eventArgs.Arguments.ToArray());
lock
(cache)
{
object
value;
//查看是否存在缓存
if
(!cache.TryGetValue(key,
out
value))
// 缓存不存在,继续执行这个方法,并将key存在MethodExecutionTag,在执行完毕的
// OnSuccess事件时使用key值将结果放到缓存中
eventArgs.MethodExecutionTag = key;
else
{
// 已经在缓存中存在,则将执行的返回值直接设置为缓存中的值,不执行方法体而立即返回
eventArgs.ReturnValue = value;
eventArgs.FlowBehavior = FlowBehavior.Return;
}
}
}
<BR>
//这个事件只有在方法体被执行了,并且执行成功没有异常发生时才会触发
public
override
void
OnSuccess(MethodExecutionArgs eventArgs)
{
// 取得缓存的key值
string
key = (
string
)eventArgs.MethodExecutionTag;
// 把执行结果放入缓存中
lock
(cache)
{
cache[key] = eventArgs.ReturnValue;
}
}
}</STRING,></STRING,>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public
static
void
Main(
string
[] args )
{
Console.WriteLine(
"1 ->"
+ GetDifficultResult( 1 ) );
Console.WriteLine(
"2 ->"
+ GetDifficultResult( 2 ) );
Console.WriteLine(
"1 ->"
+ GetDifficultResult( 1 ) );
Console.WriteLine(
"2 ->"
+ GetDifficultResult( 2 ) );
Console.ReadKey();
}
[Cache]
private
static
int
GetDifficultResult(
int
arg )
{
// 如果方法体被执行了,则会输出下面的消息,否则不会输出,说明使用了缓存
Console.WriteLine(
"Some difficult work!"
);
Thread.Sleep( 1000 );
return
arg;
}
|
1
2
3
4
5
6
7
8
9
10
|
[DbInvoke(
"ConnectionString"
)]
internal
static
class
DataLayer
{
#pragma warning disable 626
extern
static
public
void
CreateCustomer(
string
customerName,
out
int
customerId);
extern
static
public
void
ModifyCustomer(
int
customerId,
string
customerName);
extern
static
public
void
DeleteCustomer(
int
customerId);
extern
static
public
void
ReadCustomer(
int
customerId,
out
string
customerName);
#pragma warning restore 626
}
|