Log system Combat (ii)-AOP Dynamic acquisition of runtime data

Source: Internet
Author: User

Introduced

The last one has been dragged for 3 months, criticizing himself.

Through the previous article. We can take out compiled static data, such as method parameter information, through the mono reflection code. But the reality is: I need to run the data, is the user input and other external dynamic data.

Since it is dynamic, it is unknown. How do we get through the pre-injected code?

In fact, this is a question of thinking, below we have a detailed look under.

Implement a common notation
public static string GetPoint (int x, int y) {    var value=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 classWeaveservice:attribute {} Public classWeaveaction:attribute {} Public classlog:weaveaction { Public Static voidOnactionbefore (MethodBase mbbase,Object[] args) {             for(inti =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.

 public static void Weave (string[] assemblypath) {foreach (var item in assemblypath) {                var assembly = assemblydefinition.readassembly (item); var types = assembly. MainModule.Types.Where (n = n.customattributes.any (y = y.attributetype.resolve ().                Name = = "Weaveservice")); foreach (var type in types) {foreach (var method in type). Methods) {var attrs = method. Customattributes.where (y = y.attributetype.resolve ().                        Basetype.name = = "Weaveaction"); foreach (Var attr in attrs) {var resolve = attr.                            Attributetype.resolve (); var Ilprocessor = method.                            Body.getilprocessor ();                            var firstinstruction = IlProcessor.Body.Instructions.First (); var Onactionbefore = 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); }            }        }

  

three makearrayofarguments function.

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

1    /// <summary>2         ///Building Function Parameters3         /// </summary>4         /// <param name= "method" >the method to inject</param>5         /// <param name= "Firstinstruction" >The first line of instructions in the function body Il_0000:nop</param>6         /// <param name= "Writer" >mono IL processing container</param>7         /// <param name= "firstargument" >default No. 0 parameter start</param>8         /// <param name= "ArgumentCount" >number of function parameters, static data can be obtained</param>9         /// <param name= "assembly" >the assembly to inject</param>Ten          Public Static voidMakearrayofarguments (Methoddefinition method, instruction Firstinstruction, ilprocessor writer,intfirstargument, One                                           intArgumentCount, assemblydefinition Assembly) A         { -             //The first parameter value of the instance function is this (the current instance object), so start at 1.  -             intThisshift = method. IsStatic?0:1; the  -             if(ArgumentCount >0)  -             { -                 //We first create an empty array with the original function parameters, equal length.  +Writer. InsertBefore (Firstinstruction, writer. Create (OPCODES.LDC_I4, ArgumentCount-firstargument)); -                 //then instance the object array, assigning to the array we created + writer. InsertBefore (Firstinstruction, writer. Create (Opcodes.newarr, AAssembly. Mainmodule.import (typeof(Object)))); at  -                 //C # code Description -                 //object[] arr=new object[argumentcount-firstargument] -                  for(inti = firstargument; i < ArgumentCount; i++)//Traversal Parameters -                 { -                     varparameter =method. Parameters[i]; in  -                     //copy a value on the stack to writer. InsertBefore (Firstinstruction, writer. Create (Opcodes.dup)); +                     //The constant i-firstargument is stacked, and the array [i-firstargument] is the stuff.  -Writer. InsertBefore (Firstinstruction, writer. Create (OPCODES.LDC_I4, I-firstargument)); the                     //Press the i + thisshift parameter stack.  *Writer. InsertBefore (Firstinstruction, writer. Create (Opcodes.ldarg, ( Short) (i +( thisshift) )); $                     //boxing into an objectPanax Notoginseng toobject (assembly, firstinstruction, parameter. ParameterType, writer); -                     //Pressurestack to array arr[i] Assignment the writer. InsertBefore (Firstinstruction, writer. Create (Opcodes.stelem_ref)); +  A                     //C # code Description the                     //Arr[i]=value; +                 } -             } $             Else $             { - writer. InsertBefore (Firstinstruction, writer. Create (Opcodes.ldnull)); -             } the         } -          Public Static voidToobject (assemblydefinition Assembly, instruction Firstinstruction, typereference Originaltype, ILProcessor Writer)Wuyi         { the             if(Originaltype.isvaluetype) -             { Wu                 //normal value types for boxing operations - writer. InsertBefore (Firstinstruction, writer. Create (Opcodes.box, Originaltype)); About             } $             Else -             { -                 if(Originaltype.isgenericparameter) -                 { A                     //Collection Boxing + writer. InsertBefore (Firstinstruction, writer. Create (Opcodes.box, assembly. Mainmodule.import (Originaltype)); the                 } -  $             } the}

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

Four Business Preparation

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

  [Weaveservice]    public static class Usermanager    {        [Log] public        static string getusername (int userId, string MemberID)        {            return "success";        }        [Log]        public static string GetPoint (int x, int y)        {            var sum = x + y;            Return "User points:" + sum;        }    }

Our usual business notation does not require any extra action.

public static void Main (string[] args)        {                      usermanager.getusername (1, "v123465");                 Usermanager.getpoint (2, 3);            Console.ReadLine ();        }

  

Five injection calls

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

  Codeinject.weave (newstring@ "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

Mr. Mushroom

Source: http://www.cnblogs.com/mushroom/p/4124878.html

Reprint please keep the author and original address.

Log system Combat (ii)-AOP Dynamic acquisition of runtime data

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.