1
public
interface
ICalculate
2
{
3
void
Add(
int
a,
int
b);
4
}
5
6
public
class
A : ICalculate
7
{
8
#region
ICalculate 成员
9
10
public
void
Add(
int
a,
int
b)
11
{
12
Console.WriteLine(a
+
b);
13
}
14
15
#endregion
16
}
17
18
public
class
B : ICalculate
19
{
20
ICalculate _inst;
21
22
public
B(ICalculate o)
23
{
24
_inst
=
o;
25
}
26
27
#region
ICalculate 成员
28
29
public
void
Add(
int
a,
int
b)
30
{
31
Console.WriteLine(
"
Before...
"
);
32
_inst.Add(a, b);
33
Console.WriteLine(
"
After...
"
);
34
}
35
36
#endregion
37
}
38
39
class
Program
40
{
41
static
void
Main(
string
[] args)
42
{
43
Type proxyType;
//
代理类型
44
45
#region
Emit Class
46
47
AssemblyName assemblyName
=
new
AssemblyName(
"
DynamicAssemblyExample
"
);
48
AssemblyBuilder assemblyBuilder
=
AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
49
ModuleBuilder moduleBuilder
=
assemblyBuilder.DefineDynamicModule(assemblyName.Name, assemblyName.Name
+
"
.dll
"
);
50
51
TypeBuilder typeBuilder
=
moduleBuilder.DefineType(
"
DynamicAssemblyExample.Calculate
"
, TypeAttributes.Public
|
TypeAttributes.Class
52
,
typeof
(
object
),
new
Type[] {
typeof
(ICalculate) });
53
54
FieldBuilder instanceField
=
typeBuilder.DefineField(
"
_instance
"
,
typeof
(ICalculate), FieldAttributes.Private);
55
56
ConstructorBuilder constructorBuilder
=
typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard,
new
Type[] {
typeof
(ICalculate) });
57
58
ILGenerator ilGenConstructor
=
constructorBuilder.GetILGenerator();
59
ilGenConstructor.Emit(OpCodes.Ldarg_0);
60
ilGenConstructor.Emit(OpCodes.Call,
typeof
(
object
).GetConstructor(Type.EmptyTypes));
//
base.ctor()
61
ilGenConstructor.Emit(OpCodes.Ldarg_0);
62
ilGenConstructor.Emit(OpCodes.Ldarg_1);
63
ilGenConstructor.Emit(OpCodes.Stfld, instanceField);
64
ilGenConstructor.Emit(OpCodes.Ret);
65
66
MethodInfo addMethodInfo
=
typeof
(ICalculate).GetMethod(
"
Add
"
);
67
68
MethodAttributes methodAttr
=
addMethodInfo.Attributes
&
~
(MethodAttributes.Abstract);
69
70
List
<
Type
>
paramTypes
=
new
List
<
Type
>
();
71
72
foreach
(ParameterInfo pInfo
in
addMethodInfo.GetParameters())
73
{
74
paramTypes.Add(pInfo.ParameterType);
75
}
76
77
MethodBuilder addMethod
=
typeBuilder.DefineMethod(addMethodInfo.Name, methodAttr,
78
CallingConventions.Standard, addMethodInfo.ReturnType, paramTypes.ToArray());
79
80
//
writeline call
81
MethodInfo writeLineMethod
=
typeof
(Console).GetMethod(
"
WriteLine
"
,
new
Type[] {
typeof
(
string
) });
82
83
ILGenerator ilGenAddMethod
=
addMethod.GetILGenerator();
84
85
86
ilGenAddMethod.Emit(OpCodes.Ldstr,
"
Before...
"
);
87
ilGenAddMethod.Emit(OpCodes.Call, writeLineMethod);
88
89
//
每个实例方法都默认包含一个隐藏的参数,即第0个参数,它对应的是this指针,但静态方法没有隐藏的第0个参数
90
ilGenAddMethod.Emit(OpCodes.Ldarg_0);
91
ilGenAddMethod.Emit(OpCodes.Ldfld, instanceField);
92
93
94
ilGenAddMethod.Emit(OpCodes.Ldarg_1);
//
a
95
ilGenAddMethod.Emit(OpCodes.Ldarg_2);
//
b
96
ilGenAddMethod.Emit(OpCodes.Callvirt,
typeof
(ICalculate).GetMethod(
"
Add
"
));
//
a+b
97
98
ilGenAddMethod.Emit(OpCodes.Ldstr,
"
After...
"
);
99
ilGenAddMethod.Emit(OpCodes.Call, writeLineMethod);
100
101
/*
102
* Console.WriteLine(this.GetType().FullName);
103
*/
104
ilGenAddMethod.DeclareLocal(
typeof
(
int
));
105
ilGenAddMethod.Emit(OpCodes.Ldarg_0);
106
ilGenAddMethod.Emit(OpCodes.Callvirt,
typeof
(
object
).GetMethod(
"
GetType
"
));
107
ilGenAddMethod.Emit(OpCodes.Callvirt,
typeof
(Type).GetMethod(
"
get_FullName
"
));
108
ilGenAddMethod.Emit(OpCodes.Call, writeLineMethod);
109
110
111
ilGenAddMethod.Emit(OpCodes.Ret);
112
113
proxyType
=
typeBuilder.CreateType();
114
115
assemblyBuilder.Save(
"
DynamicAssemblyExample.dll
"
);
116
#endregion
117
118
ICalculate proxyImp
=
(ICalculate)proxyType.GetConstructor(
new
Type[] {
typeof
(ICalculate) })
119
.Invoke(
new
object
[] {
new
A() });
120
121
proxyImp.Add(
10
,
20
);
122
}
123
}