Log System Practice (I)-AOP Static injection

Source: Internet
Author: User

 

Background

Recently, when writing a log system, you need to inject log records into the function at runtime with function information. At this time, I thought of using AOP.

Technical Analysis

AOP is divided into Dynamic Injection and Static injection.

Dynamic Injection Mode

1: remoting contextattribute context (poor performance ).

2: Dynamic proxy (reflection). Most AOP frameworks use this method.

3: MVC filter, also reflected.

First, the performance is too poor to consider. Type 2: Dynamic proxies are used in the production environment to keep logs, which is not recommended because the performance consumption is not small. Third: only the UI layer can be used. The other layer is the same as the second layer.

Static injection method (This article focuses on ).

1: Based on IL injection, the loss is negligible. Postsharp adopts this method.

Technical implementation:

1: declare attribute

Public class weavesign: attribute {} public class weaveaction: attribute {} public class log: weaveaction {public static void onactionbefore (methodbase mbbase) {// all information about the mbbase method to be injected var T = mbbase. getparameters (); logmanager. record ();}}

  

 

2: Mark the method to be injected

[Log]public static string GetUserName(int userId){        return "Vidar";}

 

3: il injection (Key Point), using mono. Cecil

Private Static void weave (ienumerable <Assembly> assemblylist) {// assemblylist the Assembly list to be injected. Foreach (VAR item in assemblylist) {var filepath = item. codebase. substring (8, item. codebase. length-8); // read the Assembly var Assembly = assemblydefinition. readassembly (filepath); // obtain the type injection mark of the weavesign type var types = assembly. mainmodule. types. where (n => N. customattributes. any (y => Y. attributetype. resolve (). name = "weavesign"); foreach (VAR type in types) {foreach (VaR method in type. methods) {// obtain weavea VaR attrs = method. customattributes. where (y => Y. attributetype. resolve (). basetype. name = "weaveaction"); foreach (var attr in attrs) {// Restore Type var resolve = ATTR. attributetype. resolve (); // obtain the VaR ilprocessor = method of the il container. body. getilprocessor (); var firstinstruction = ilprocessor. body. instructions. first (); // locate the onactionbefore method of the tag type. VaR onactionbefore = resolve. getmethods (). single (n => N. name = "onactionbefore"); // create a system. reflection. methodbase. the getcurrentmethod () method references var mfreference = assembly. mainmodule. import (typeof (system. reflection. methodbase ). getmethod ("getcurrentmethod"); // inject to Il (call getcurrentmethod, stack) ilprocessor. insertbefore (firstinstruction, ilprocessor. create (Opcodes. call, mfreference); // creates a call (CALL) marking method onactionbefore ilprocessor. insertbefore (firstinstruction, ilprocessor. create (Opcodes. call, onactionbefore) ;}} if (types. any () {// write Assembly assembly. write (filepath );}}}

3: After compilation is successful. The following code is displayed during decompilation.

 

Il

  .method public hidebysig static string GetUserName(int32 userId) cil managed{    .custom instance void TestLibrary.Log::.ctor()    .maxstack 1    .locals init (        [0] string str)    L_0000: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetCurrentMethod()    L_0005: call void TestLibrary.Log::OnActionBefore(class [mscorlib]System.Reflection.MethodBase)    L_000a: nop     L_000b: ldstr "Vidar"    L_0010: stloc.0     L_0011: br.s L_0013    L_0013: ldloc.0     L_0014: ret } 

C #

[Log]public static string GetUserName(int userId){    Log.OnActionBefore(MethodBase.GetCurrentMethod());    return "Vidar";}

 

Supplement:

This article focuses on the core implementation ideas.

 

Log System Practice (I)-AOP Static injection

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.