Proxy object in Aspect #

xiaoxiao2021-03-06  67

The agent object is a key section of AOP dynamic interception. Below to analyze how agent objects are defined.

1. CreateProxyTypeinternal static Type CreateProxyType (Type [] interfaces, IMixin [] mixins) {// ... AssemblyName assemblyName = new AssemblyName (); assemblyName.Name = "DynamicAssemblyProxyGen";

AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (assemblyName, AssemblyBuilderAccess.Run);. // define the access mode to specify the name and dynamic assembly, where the assembly to establish the operating mode ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule (assemblyName.Name, true) // Define a dynamic module in the dynamic program set, and the second parameter emits symbol information.

TypeBuilder typeBuilder = moduleBuilder.DefineType ( "ProxyType", TypeAttributes.Public | TypeAttributes.Class, null, MergeTypes (interfaces, mixins)); // define a class type, such as public, and achieve all interfaces and interfaces mixins, // Mergetype is used to merge Interfaces and Mixins into a TYPE [].

Fieldbuilder Handlerfield = Generatefield (TypeBuilder, IINVOCATIONHandler); // Generate an IinvocationHandler field. It is equivalent to public IinvocationHandler Handler;

FieldBuilder mixinHandlerField = GenerateField (typeBuilder, mixinHandlerFieldName, typeof (IMixinInvocationHandler)); // IMixinInvocation generating a field equivalent public IMixinInvocationHandler mixinHandler;. FieldBuilder mixinsField = GenerateField (typeBuilder, "mixins", typeof (IMixin [])); // generated A iMixin [] field, equivalent to public immixin [] mixins;

ConstructorBuilder Constr = GenerateConstructor (TypeBuilder, Handlerfield, Mixinsfield, MixinHandlerfield); // Generate a constructor.

GenerateInterfaceImplementation (TypeBuilder, Interfaces, Handlerfield); // Generates an implementation section of the interface.

GenerateMixinImplementation (typeBuilder, mixins, mixinHandlerField, mixinsField);.. // create means for implementing the interface portion of the mixer} 2 GenerateConstructorprivate static ConstructorBuilder GenerateConstructor (TypeBuilder typeBuilder, FieldBuilder handlerField, FieldBuilder mixinsField, FieldBuilder mixinHandlerField) {ConstructorBuilder consBuilder = typeBuilder.DefineConstructor (MethodAttributes .Public, callingconventions.standard, new type [] {typeof (iinvocationhandler), typeof (iMixinivationHandler), typeof (iMixin [])}); // Defines a constructor, specifying method is modified as public, and the call is convention to be STANDARD. / / I am equivalent to public proxytype (IinvocationHandler, iMixinivationHandler MixinHandler, iMixin [] mixins; ilgenerator ilgenerator = consBuilder.getilGenerator (); // acquisition IL generator. Used to generate IL code.

Ilgenerator.emit (opcodes.ldarg_0); ilgenerator.emit (opcodes.call, typeof (object) .getconstructor (new type [0])); // call the default constructor of the Object type, equivalent to public proxytype (... : base () // handler ilgenerator.emit (opcodes.ldarg_0); ilgenerator.emit (opcodes.ldarg_1); ilgenerator.emit (opcodes.stfld, handlerfield); / / assigning the Handlerfield field, equivalent to this.Handler = handler; // mixinHandler ilGenerator.Emit (OpCodes.Ldarg_0); ilGenerator.Emit (OpCodes.Ldarg_2); ilGenerator.Emit (OpCodes.Stfld, mixinHandlerField); // for mixinHandlerField field assignment, equivalent to this.mixinHandler = mixinHandler ;

// mixins ilgenerator.emit (opcodes.ldarg_0); ilgenerator.emit (opcodes.ldarg_3); ilgenerator.emit (opcodes.stfld, mixinsfield); / / assignment to the Mixinsfield field, equivalent to this.mixins = Mixins

Ilgenerator.emit (opcodes.ret);

Return consBuilder;}

The construction method of the agent object is similar to:

public Class ProxyType: object interface, the interface mixer {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. Generate the implementation of the interface

static void GenerateInterfaceImplementation (TypeBuilder typeBuilder, Type [] interfaces, FieldBuilder handlerField) {foreach (Type inter in interfaces) {GenerateInterfaceImplementation (typeBuilder, inter, handlerField, null, -1);} // iterate through all interfaces.}

Private static void generatemixinimplement (Typein [] Mixins, FieldBuilder MixinHandlerfield, Fieldbuilder Mixinsfield) {if (mixins == null) return;

For (int i = 0; i

Foreach (Type Inter in Interfaces) {GenerateInterfaceImplement (Typebuilder, Inter, MixinHandlerfield, Mixinsfield, i);}} // Traverse all mixer interface}

Static void GenerateInterfaceImplement (Typebuilder Typebuilder, Type Inter, Fieldbuilder Handlerfield, Fieldbuilder Mixinsfield, int mixinposition) {// ...

Type [] baseinterfaces = inter .findinterfaces (new typefilter (nofilterImpl), inter); generateInterfaceImplementation (TypeBuilder, BaseInterface, handlerfield); // This is a recursive process for traversing all interfaces.

PropertyInfo [] properties = inter.GetProperties (); PropertyBuilder [] propertiesBuilder = new PropertyBuilder [properties.Length]; for (int i = 0; i

// achieve .private static void GeneratePropertyImplementation (TypeBuilder typeBuilder, PropertyInfo property, ref PropertyBuilder propertyBuilder) {propertyBuilder = typeBuilder.DefineProperty (property.Name, property.Attributes, property.PropertyType, null) attribute; // be by calling method DefindProperty Generate an implementation of the properties.

Method implemented .private static // void GenerateMethodImplementation (TypeBuilder typeBuilder, MethodInfo method, PropertyBuilder [] properties, Type inter, FieldBuilder handlerField, FieldBuilder mixinsField, int mixinPosition) {ParameterInfo [] parameterInfo = method.GetParameters (); // obtain parameters information.

System.Type [] parameters = new system.type [parameterinfo.length]; for (int i = 0; i

Parameters [i] = parameterInfo [i] .parameterType;

}

// Get the type of parameters.

MethodAttributes atts = MethodAttributes.Public | MethodAttributes.Virtual; if (method.Name.StartsWith ( "set_") || method.Name.StartsWith ( "get_")) {atts = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.Virtual } // Specify the modification of the method.

MethodBuilder methodBuilder = typeBuilder.DefineMethod (method.Name, atts, CallingConventions.Standard, method.ReturnType, parameters); // definition method .if (method.Name.StartsWith ( "set_") || method.Name.StartsWith ( " Get_ ")) {forEach (PropertyBuilder Property In Properties) {if (Property == Null) {Break;}

if (! property.name.equals ( )))) {Continue;}

IF (Methodbuilder.name.startSwith) {Property.setSetMethod (MethodBuilder); Break;} else {profrty.setgetMethod (MethodBuilder); Break;}} // If the method begins with SET_ or GET_, then Traverse all properties, set the SET / GET method for the attribute if the name is the same.

WriteilFormethod (MethodBuilder, Parameters, Handlerfield, Mixinsfield, MixInPosition); // method IL code.

The specific code implemented by the method, this is a key, interception and mixing should be handled here.

Private Static Void WriteilFormethod (Methodbuilder Builder, System.Type [] Parameters, Fieldbuilder Handlerfield, Fieldbuilder Mixinsfield, Int MixInPosition) {Int ArrayPositionInstack = 1;

Ilgenerator ilgenerator = builder.getilGenerator ();

Ilgenerator.DeclareLocal (TypeF (MethodBase)); // Defines a local variable for a MothoDBase type.

IF (Builder.Returntype! = typeof (void) {ilgenerator.deClareLocal (Builder.ReturNType); ArrayPositionInstack = 2;} // If there is a return value, define a local variable to save the return value.

Ilgenerator.DeclareLocal (TypeOf (object [])); // Defines a partial change of an Object [] type.

ilGenerator.Emit (OpCodes.Call, typeof (MethodBase) .GetMethod ( "GetCurrentMethod")); // call GetCurrentMethod method .ilGenerator.Emit (OpCodes.Stloc_0); ilGenerator.Emit (OpCodes.Ldarg_0); ilGenerator.Emit (OpCodes .Ldfld, handlerfield; // this ilgenerator.emit (opcodes.ldarg_0);

//Method base ilgenerator.emit (opcodes.ldloc_0); // mixin if (mixinPosition> -1) {ilgenerator.emit (opcodes.ldarg_0); ilgenerator.emit (opcodes.ldfld, mixinsfield; ilgenerator.emit); ilgenerator.emit (Opcodes. LDC_I4, MixInPosition; Ilgenerator.emit (opcodes.ldelem_ref);

// arguments ilgenerator.emit (opcodes.ldc_i4, parameters.Length); Ilgenerator.emit (Opcodes.newarr, TypeOf (Object));

IF (parameters.length! = 0) {ilgenerator.emit (opcodes.stloc, arraypositionInstack; ilgenerator.emit (opcodes.ldloc, arraypositioninstack);}

For (int C = 0; C

Ilgenerator.emit (opcodes.ldc_i4, c);

Ilgenerator.emit (Opcodes.ldarg, C 1);

IF (Parameters [C] .issvalueType) {ilgenerator.emit (opcodes.box, parameters [c] .underlyingsystemType);}

Ilgenerator.emit (opcodes.stelem_ref); ilgenerator.emit (opcodes.ldloc, arraypositioninstack);}

switch (handlerField.Name) {case mixinHandlerFieldName: {ilGenerator.Emit (OpCodes.Callvirt, typeof (IMixinInvocationHandler) .GetMethod ( "Invoke")); break;} default: {ilGenerator.Emit (OpCodes.Callvirt, typeof (IInvocationHandler) .GetMethod ("invoke")); Break;}} // is processed according to the name of the field. OpCodes.callvirtr is specified as later binding. // If the field belongs to a mixer interface, execute iMixinivationHandler.invoke, / / ​​otherwise call IInvocationHandler.Invoke.if (builder.ReturnType = typeof (void)!) {if {ilGenerator.Emit (OpCodes.Castclass, builder.ReturnType) (builder.ReturnType.IsValueType!);} else {ilGenerator.Emit (OpCodes.Unbox , builder.returntype; ilgenerator.emit (convertTyPetoPcode (Builder.Returntype);}

Ilgenerator.emit (opcodes.stloc, 1);

Label label = ilgenerator.defineLabel (); ilgenerator.emit (opcodes.br_s, label); Ilgenerator.markLabel (Label); Ilgenerator.emit (Opcodes.ldloc, 1);} else {ilgenerator.emit (opcodes.pop); }

Ilgenerator.emit (opcodes.ret);} // Don't be very familiar with IL, some details are not clear. His friends who are familiar with IL will be corrected and supplemented.

转载请注明原文地址:https://www.9cbs.com/read-119575.html

New Post(0)