Dynamic acquisition of runtime data using mono Cecil (injected in atribute form)-From the network

Source: Internet
Author: User

Catalogue

One: Common wording

Two: injection definition

Three: Weave function

Four: Parameter construction

Five: Business Preparation

Six: Inject call

One: Common wording
1234 publicstatic string GetPoint(int x, int y) {    varvalue=x;}

Wow, that's so easy. In fact, dynamic acquisition and our normal write code is the same, we put the code to inject, generate a received variable on it.

Just like the value above, and then pass it on to our own function.

Two: injection definition
  public class Weaveservice:attribute    {    } public class    Weaveaction:attribute    {    } public    class  Log:weaveaction    {public        static void Onactionbefore (MethodBase mbbase, object[] args)        {for            (int i = 0; I < args. Length; i++)            {                Console.WriteLine (string. Format ("{0} method, the {1} parameter is: {2}", Mbbase.name,i, Args[i]));}}    

Weaveservice Weaveaction 2 attribute is an injected marker that allows us to quickly locate in the injection finder.

Onactionbefore is our receive function, and ARG is the parameter at which the function runs.

Three: Weave function

This piece of code has been commented on in detail in the previous article and is not much described here.

12345678910111213141516171819202122232425262728293031323334 publicstatic voidWeave(string[] assemblyPath)       {           foreach(varitem inassemblyPath)           {               varassembly = AssemblyDefinition.ReadAssembly(item);               vartypes = assembly.MainModule.Types.Where(n => n.CustomAttributes.Any(y => y.AttributeType.Resolve().Name == "WeaveService"));                foreach(vartype intypes)               {                   foreach(varmethod intype.Methods)                   {                       varattrs =                           method.CustomAttributes.Where(y => y.AttributeType.Resolve().BaseType.Name == "WeaveAction");                       foreach(varattr inattrs)                       {                           varresolve = attr.AttributeType.Resolve();                           varilProcessor = method.Body.GetILProcessor();                           varfirstInstruction = ilProcessor.Body.Instructions.First();                           varonActionBefore = resolve.GetMethods().Single(n => n.Name == "OnActionBefore");                           var mfReference = assembly.MainModule.Import(typeof(System.Reflection.MethodBase).GetMethod("GetCurrentMethod"));                           ilProcessor.InsertBefore(firstInstruction, ilProcessor.Create(OpCodes.Call, mfReference));                           MakeArrayOfArguments(method, firstInstruction, ilProcessor, 0, method.Parameters.Count, assembly);                           ilProcessor.InsertBefore(firstInstruction, ilProcessor.Create(OpCodes.Call, onActionBefore));                       }                   }               }               if(types.Any())               {                   assembly.Write(item);               }           }       }
Four: Parameter construction

The function that gets the function parameter dynamically, the code has the detailed comment.

 1//<summary> 2///Build function Parameters 3///</summary> 4//<param Name= "method" > to inject Method </param> 5//<param name= "firstinstruction" > function body the first line of instructions recognized il_0000:nop</param> 6///& Lt;param name= "Writer" >mono il processing container </param> 7//<param name= "firstargument" > Default No. 0 parameter start </param&gt ; 8//<param name= "ArgumentCount" > The number of function parameters, static data can be obtained </param> 9//<param name= "assembly" > Assembly to inject </param>10 public static void Makearrayofarguments (Methoddefinition method, instruction Firstinstruct Ion, ilprocessor writer, int firstargument,11 int argumentcount, assemblydefinit Ion assembly) 12 {13///instance function The first parameter value is this (the current instance object), so start with 1. int Thisshift = method. IsStatic? 0:1;15 if (ArgumentCount > 0) 17 {18//We first create an empty array with the original function parameters, equal length. Writer. InsertbefoRe (firstinstruction, writer. Create (OPCODES.LDC_I4, argumentcount-firstargument)); 20//Then instance of the object array, assigned to the array we created writ Er. InsertBefore (Firstinstruction, writer. Create (opcodes.newarr,22 assembly. Mainmodule.import (typeof (object)));//c# code description//object[] Arr=new Object[argumentcou Nt-firstargument] + for (int i = firstargument; i < ArgumentCount; i++)//Traverse parameter 27 {2 8 var parameter = method. parameters[i];29 30//Copy a value on the stack the writer. InsertBefore (Firstinstruction, writer. Create (Opcodes.dup)); 32//Constant i-firstargument to stack, array [i-firstargument] this stuff. Writer. InsertBefore (Firstinstruction, writer.  Create (OPCODES.LDC_I4, I-firstargument)), 34//press the i + thisshift parameter stack. Writer. InsertBefore (Firstinstruction, WRIter.  Create (Opcodes.ldarg, (short) (i + Thisshift))), 36//boxed into Object37 toobject (assembly, Firstinstruction, parameter. ParameterType, writer), 38//stack to the array arr[i] assigns a value of the number of writer. InsertBefore (Firstinstruction, writer. Create (Opcodes.stelem_ref));//c# code Description//arr[i]=value;43}4 4}45 Else46 {writer. InsertBefore (Firstinstruction, writer. Create (Opcodes.ldnull));}49}50 public static void Toobject (Assemblydefinition assembly, in Struction firstinstruction, TypeReference Originaltype, ilprocessor writer) Wuyi {if (ORIGINALTYPE.ISV Aluetype) 53 {54//Normal value type for boxing operation, writer. InsertBefore (Firstinstruction, writer. Create (Opcodes.box, Originaltype)),}57 else58 {if (origInaltype.isgenericparameter) 60 {61//collection boxed by writer. InsertBefore (Firstinstruction, writer. Create (Opcodes.box, assembly. Mainmodule.import (Originaltype)); 63}64 65}66}

Introduces the function of the next mono InsertBefore. This function inserts an instruction before an instruction. Take a picture.

We can see from the diagram that the first line of instruction is IL_0000:NOP. The first line is appended with the LDC.I4 2 instruction, and the second row we are still NOP before. Top

Five: Business Preparation

I define a user class to inject, and then tag it.

1234567891011121314151617 [WeaveService]  publicstaticclassUserManager  {      [Log]      publicstaticstringGetUserName(intuserId, stringmemberid)      {          return "成功";      }      [Log]      publicstaticstringGetPoint(intx, inty)      {          varsum = x + y;          return"用户积分: "+ sum;      }  }

Our usual business notation does not require any extra action.

123456789 publicstaticvoidMain(string[] args)       {                    UserManager.GetUserName(1,"v123465");               UserManager.GetPoint(2, 3);           Console.ReadLine();       }
Six: Inject call

I typed the business class into the D drive and injected it with our previous weave function.

  Codeinject.weave (New string[] {@ "D:\test\Test.exe"});

The operation results are as follows

Post-compilation C #

Summarize

Through static injection, we can better understand the Il language from the use.

Getting Dynamic Data is just a pick. With mono we can write our own AOP static components.

Reference Resources

1:postsharp Source

2:http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes_fields (v=vs.110). aspx

Dynamic acquisition of runtime data using mono Cecil (injected in atribute form)-From the network

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.