代理對象是AOP動態截入的關鍵部分
internal static Type CreateProxyType(Type[] interfaces
//
AssemblyName assemblyName = new AssemblyName();
assemblyName
AssemblyBuilder assemblyBuilder = AppDomain
assemblyName
// 以指定名稱和訪問模式定義動態程序集
ModuleBuilder moduleBuilder = assemblyBuilder
// 在動態程序集中定義動態模塊
TypeBuilder typeBuilder = moduleBuilder
TypeAttributes
// 定義一個類類型
// MergeTypes用於將interfaces和mixins合並為一個Type[]
FieldBuilder handlerField = GenerateField( typeBuilder
// 產生一個IInvocationHandler字段
FieldBuilder mixinHandlerField = GenerateField( typeBuilder
typeof(IMixinInvocationHandler) );
// 產生一個IMixinInvocation字段
FieldBuilder mixinsField = GenerateField( typeBuilder
// 產生一個IMixin[]字段
ConstructorBuilder constr = GenerateConstructor( typeBuilder
// 產生一個構造方法
GenerateInterfaceImplementation( typeBuilder
// 產生接口的實現部分
GenerateMixinImplementation( typeBuilder
// 產生混合器接口的實現部分
}
private static ConstructorBuilder GenerateConstructor( TypeBuilder typeBuilder
FieldBuilder handlerField
ConstructorBuilder consBuilder = typeBuilder
MethodAttributes
CallingConventions
new Type[] { typeof(IInvocationHandler)
// 定義一個構造方法
// 等同於 public ProxyType( IInvocationHandler handler
ILGenerator ilGenerator = consBuilder
// 取得IL產生器
ilGenerator
ilGenerator
// 調用Object類型的默認構造函數
// handler
ilGenerator
ilGenerator
ilGenerator
// 對handlerField字段進行賦值
// mixinHandler
ilGenerator
ilGenerator
ilGenerator
// 對mixinHandlerField字段進行賦值
// mixins
ilGenerator
ilGenerator
ilGenerator
// 對mixinsField字段進行賦值
ilGenerator
return consBuilder;
}
代理對象的構造方法類似如下:
public Class ProxyType : 對象接口
private IInvocationHandler handler;
private IMixinvocationHandler mixinHandler;
private IMixin[] mixins;
public public ProxyType( IInvocationHandler handler
IMixinInvocationHandler mixinHandler
this
this
this
}
//
}
static void GenerateInterfaceImplementation( TypeBuilder typeBuilder
Type[] interfaces
foreach(Type inter in interfaces) {
GenerateInterfaceImplementation( typeBuilder
}
// 遍歷所有接口
}
private static void GenerateMixinImplementation( TypeBuilder typeBuilder
IMixin[] mixins
if (mixins == null) return;
for(int 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;
} From:http://tw.wingwit.com/Article/program/net/201311/13593.html