代理对象是AOP动态截入的关键部分. 下面来分析一下代理对象是如何定义的.
1. CreateProxyType internal static Type CreateProxyType(Type[] interfaces, IMixin[] mixins) {
//...
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "DynamicAssemblyProxyGen";
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
assemblyName, AssemblyBuilderAccess.Run);
// 以指定名称和访问模式定义动态程序集, 这里以运行模式建立程序集.
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule( assemblyName.Name, true );
// 在动态程序集中定义动态模块, 第二个参数发出符号信息.
TypeBuilder typeBuilder = moduleBuilder.DefineType( "ProxyType",
TypeAttributes.Public|TypeAttributes.Class, null, MergeTypes(interfaces, mixins) );
// 定义一个类类型, 此类为public, 且实现所有的interfaces和mixins接口,
// MergeTypes用于将interfaces和mixins合并为一个Type[].
FieldBuilder handlerField = GenerateField( typeBuilder, handlerFieldName, typeof(IInvocationHandler) );
// 产生一个IInvocationHandler字段. 等同于 public IInvocationHandler handler;
FieldBuilder mixinHandlerField = GenerateField( typeBuilder, mixinHandlerFieldName,
typeof(IMixinInvocationHandler) );
// 产生一个IMixinInvocation字段. 等同于 public IMixinInvocationHandler mixinHandler;
FieldBuilder mixinsField = GenerateField( typeBuilder, "mixins", typeof(IMixin[]) );
// 产生一个IMixin[]字段, 等同于 public IMixin[] mixins;
ConstructorBuilder constr = GenerateConstructor( typeBuilder, handlerField, mixinsField, mixinHandlerField );
// 产生一个构造方法.
GenerateInterfaceImplementation( typeBuilder, interfaces, handlerField );
// 产生接口的实现部分.
GenerateMixinImplementation( typeBuilder, mixins, mixinHandlerField, mixinsField);
// 产生混合器接口的实现部分.
}
2. GenerateConstructor private static ConstructorBuilder GenerateConstructor( TypeBuilder typeBuilder,
FieldBuilder handlerField, FieldBuilder mixinsField, FieldBuilder mixinHandlerField ) {
ConstructorBuilder consBuilder = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
new Type[] { typeof(IInvocationHandler), typeof(IMixinInvocationHandler), typeof(IMixin[]) } );
// 定义一个构造方法, 指定方法修饰为Public, 调用约定为Standard.
// 等同于 public ProxyType( IInvocationHandler handler, IMixinInvocationHandler mixinHandler, IMixin[] mixins );
ILGenerator ilGenerator = consBuilder.GetILGenerator();
// 取得IL产生器. 用于生成IL代码.
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Call, typeof(Object).GetConstructor(new Type[0]));
// 调用Object类型的默认构造函数, 等同于 public ProxyType(...) : base()
// handler
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Stfld, handlerField);
// 对handlerField字段进行赋值, 等同于 this.handler = handler;
// mixinHandler
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_2);
ilGenerator.Emit(OpCodes.Stfld, mixinHandlerField);
// 对mixinHandlerField字段进行赋值, 等同于 this.mixinHandler = mixinHandler;
// mixins
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_3);
ilGenerator.Emit(OpCodes.Stfld, mixinsField);
// 对mixinsField字段进行赋值, 等同于 this.mixins = mixins
ilGenerator.Emit(OpCodes.Ret);
return consBuilder;
}
代理对象的构造方法类似如下:
public Class ProxyType : 对象接口, 混合器接口 {
private IInvocationHandler handler;
private IMixinvocationHandler mixinHandler;
private IMixin[] mixins;
public public ProxyType( IInvocationHandler handler,
IMixinInvocationHandler mixinHandler, IMixin[] mixins ); {
this.handler = handler;
this.mixinHandler = mixinHandler;
this.mixins = mixins;
}
// ...
}
3. 产生接口的实现部分
static void GenerateInterfaceImplementation( TypeBuilder typeBuilder,
Type[] interfaces, FieldBuilder handlerField ) {
foreach(Type inter in interfaces) {
GenerateInterfaceImplementation( typeBuilder, inter, handlerField, null, -1 );
}
// 遍历所有接口.
}
private static void GenerateMixinImplementation( TypeBuilder typeBuilder,
IMixin[] mixins, FieldBuilder mixinHandlerField, FieldBuilder mixinsField) {
if (mixins == null) return;
for(int i = 0; i < mixins.Length; i++) {
Type[] interfaces = mixins[i].GetType().GetInterfaces();
foreach(Type inter in interfaces) {
GenerateInterfaceImplementation( typeBuilder, inter, mixinHandlerField, mixinsField, i );
}
}
// 遍历所有的混合器接口
}
static void GenerateInterfaceImplementation( TypeBuilder typeBuilder,
Type inter, FieldBuilder handlerField, FieldBuilder mixinsField, int mixinPosition) {
// ...
Type[] baseInterfaces = inter.FindInterfaces( new TypeFilter( NoFilterImpl ), inter );
GenerateInterfaceImplementation( typeBuilder, baseInterfaces, handlerField);
// 这是一个递归过程, 用于遍历所有的接口.
PropertyInfo[] properties = inter.GetProperties();
PropertyBuilder[] propertiesBuilder = new PropertyBuilder[properties.Length];
for(int i=0; i < properties.Length; i++) {
GeneratePropertyImplementation( typeBuilder, properties[i], ref propertiesBuilder[i] );
}
// 产生属性的实现.
MethodInfo[] methods = inter.GetMethods();
foreach(MethodInfo method in methods) {
GenerateMethodImplementation( typeBuilder, method, propertiesBuilder, inter,
handlerField, mixinsField, mixinPosition );
}
// 产生方法的实现.
}
// 属性的实现.
private static void GeneratePropertyImplementation( TypeBuilder typeBuilder,
PropertyInfo property, ref PropertyBuilder propertyBuilder ) {
propertyBuilder = typeBuilder.DefineProperty(
property.Name, property.Attributes, property.PropertyType, null);
// 通过调用DefindProperty方法来产生属性的实现部分.
}
// 方法的实现.
private static void GenerateMethodImplementation( TypeBuilder typeBuilder,
MethodInfo method, PropertyBuilder[] properties, Type inter,
FieldBuilder handlerField, FieldBuilder mixinsField, int mixinPosition ) {
ParameterInfo[] parameterInfo = method.GetParameters();
// 取得参数信息.
System.Type[] parameters = new System.Type[parameterInfo.Length];
for (int i=0; i
parameters[i] = parameterInfo[i].ParameterType;
}
// 取得参数的类型.
MethodAttributes atts = MethodAttributes.Public|MethodAttributes.Virtual;
if ( method.Name.StartsWith("set_") || method.Name.StartsWith("get_") ) {
atts = MethodAttributes.Public|MethodAttributes.SpecialName|MethodAttributes.Virtual;
}
// 指定方法的修饰.
MethodBuilder methodBuilder = typeBuilder.DefineMethod( method.Name, atts,
CallingConventions.Standard, method.ReturnType, parameters );
// 定义方法.
if ( method.Name.StartsWith("set_") || method.Name.StartsWith("get_") ) {
foreach( PropertyBuilder property in properties ) {
if (property == null) {
break;
}
if (!property.Name.Equals( method.Name.Substring(4) )) {
continue;
}