天天看點

MSBuild + MSILInect實作編譯時AOP之預覽

class diagram:

MSBuild + MSILInect實作編譯時AOP之預覽

1:imethodinject:interface,擁有executeing,exceptioned,executesuccess三個契約為别為執行前,異常,成功。它們都有公同的參數類型:methodexecutioneventargs

MSBuild + MSILInect實作編譯時AOP之預覽

    executeing:傳回值為bool類型,将決定是否繼續執行方法體。exceptioned:屬性eeption代表發生的異常資訊,傳回值exceptionstrategy(取值:handle, rethrow, thrownew)決定異常處理機制,handle已處理并忽略,rethrow重新抛出,thrownew抛出一個包裝後的來源于methodexecutioneventargs 的exception。executesuccess,對于擁有傳回值的方法,可以修改methodexecutioneventargs 的returnvalue,修改傳回值。最後methodexecutioneventargs的order決定多個attribute的注入先後,即方法截獲的先後順序。

1:methodinterceptbase:針對于方法attribute标簽,實作方法截獲

MSBuild + MSILInect實作編譯時AOP之預覽
MSBuild + MSILInect實作編譯時AOP之預覽

[attributeusage(attributetargets.method, inherited = false, allowmultiple = false)]

    public class methodinterceptbase : attribute, imethodinject

    {

        public int order

        {

            get;

            set;

        }

        #region imethodinject members

        public virtual bool executeing(methodexecutioneventargs args)

            return true;

        public virtual exceptionstrategy exceptioned(methodexecutioneventargs args)

            return exceptionstrategy.rethrow;

        public virtual void executesuccess(methodexecutioneventargs args)

        #endregion

}

MSBuild + MSILInect實作編譯時AOP之預覽

2:matchedmethodinterceptbase:和上面方法之上的methodinterceptbase大體一緻,差別在于其應用于class之上,屬性rule為截獲方法比對(應用于多個方法之上相同截獲),支援*比對。

MSBuild + MSILInect實作編譯時AOP之預覽
MSBuild + MSILInect實作編譯時AOP之預覽

[attributeusage(attributetargets.class, inherited = false, allowmultiple = false)]

    public class matchedmethodinterceptbase : attribute, imethodinject

        public string rule

    }

MSBuild + MSILInect實作編譯時AOP之預覽

3:propertyinterceptbase:實作屬性的注入,其屬性action(enum propertyinterceptaction:none get, set)指注入屬性的get或者set; 

MSBuild + MSILInect實作編譯時AOP之預覽
MSBuild + MSILInect實作編譯時AOP之預覽

[attributeusage(attributetargets.property, inherited = false, allowmultiple = false)]

    public class propertyinterceptbase : attribute, imethodinject

        public propertyinterceptaction action

MSBuild + MSILInect實作編譯時AOP之預覽

其上預設都是executeing繼續執行,exceptioned為抛出不處理,成功不修改result。

下面是一個簡單測試code:

MSBuild + MSILInect實作編譯時AOP之預覽
MSBuild + MSILInect實作編譯時AOP之預覽

using system;

using system.collections.generic;

using system.linq;

using system.text;

using system.reflection;

using green.aop;

namespace test

{   

    // [testaop2attribute(rule = "testmethod1*")]

    public class class1

        // [testaoppropertyattribute(action = propertyinterceptaction.set)]

        [testaoppropertygetattribute(action = propertyinterceptaction.get)]

        public teststrust testproperty

        [obsolete()]

        public static void main(string[] args)

        {          

            try

            {

                var y = new class1();

                // y.testproperty = datetime.now;

                console.writeline(y.testproperty);

            }

            catch (exception ex)

                console.writeline(ex.tostring());

            // new class1().testmethod1(1, 2, null);

            console.read();

            //throw new exception("exfffffffffffffffffffff");

        //[testaopattribute(order=1)]

        //[testaop1attribute(testproperty = 1, template = "sdsdsd",order=0)]

        public class1 testmethod1(int i, int j, class1 c)

            console.writeline("ok");

            return new class1();

    public class testaoppropertygetattribute : green.aop.propertyinterceptbase

        public override bool executeing(green.aop.methodexecutioneventargs args)

            console.writeline("------------------" + args);

            console.writeline(args.instance);

            console.writeline(args.method);

            console.writeline(this.gettype() + ":" + "executeing");

        public override green.aop.exceptionstrategy exceptioned(green.aop.methodexecutioneventargs args)

            console.writeline(this.gettype() + ":" + "exceptioned");

            return green.aop.exceptionstrategy.rethrow;

        public override void executesuccess(green.aop.methodexecutioneventargs args)

            console.writeline("-----------");

            console.writeline(this.gettype() + ":" + "executesuccess" + "--result:" + args.returnvalue);

    public class testaoppropertyattribute : green.aop.propertyinterceptbase

            return green.aop.exceptionstrategy.handle;

       {

            console.writeline(this.gettype() + ":" + "executesuccess");

    public class testaop2attribute : green.aop.matchedmethodinterceptbase

        public bool match(system.reflection.methodbase method)

    //[attributeusage(attributetargets.method)]

    public class testaopattribute : green.aop.methodinterceptbase

    [attributeusage(attributetargets.method)]

    public class testaop1attribute : attribute, green.aop.imethodinject

        public int testproperty

        public string template

        public bool executeing(green.aop.methodexecutioneventargs args)

        public green.aop.exceptionstrategy exceptioned(green.aop.methodexecutioneventargs args)

        public void executesuccess(green.aop.methodexecutioneventargs args)

MSBuild + MSILInect實作編譯時AOP之預覽

 注意測試有兩種方式(由于沒有安裝包):

1:先重編譯測試項目,運作consoleapplication2(在屬性中修改控制台其實參數)。在檢視測試項目。

在後續将會從簡單demo分析實作原理。