博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 使用Emit实现动态AOP框架 (一)
阅读量:4877 次
发布时间:2019-06-11

本文共 3880 字,大约阅读时间需要 12 分钟。

     目  录

  最近需要有一个完全自主的基于C#语言的Aop框架,查了一下资料实现方式主要分为:静态织入和动态代理,静态织入以Postshop为代表,而动态代理又分为:

1、普通反射

2、Emit反射

3、微软提供的.Net Remoting和RealProxy

(微软官方例子)

      总体来说静态织入速度最快,普通反射最慢,而.Net Remoting和RealProx实现起来又相对较复杂。而Emit速度居中,同时其一次生成后,将结果序列化,速度也并不慢,同时和原有类并没有紧密耦合,通过外部配置文件可以方便的控制要进行代理的类型、方法和属性,其缺点是被代理的方法、属性必须为virtual类型。

一、被代理类和代理类

       被代理类,是我们正常使用的类,里边是原有的业务逻辑,只要在被代理方法上申明上相应的切面特性就行了,使用起来比较简单;如下

1   public class AopTest 2   { 3          4         public AopTest() 5         { 6             Name = "小明"; Age = 10; 7         } 8  9         public AopTest(string name, int age)10         {11             Name = name; Age = age;12         }13 14         [Log]15         public virtual string Name { get; set; }16 17         [Log]18         public virtual int Age { get; set; }19 20         [Log]21         public virtual int NYearLater(int a)22         {23             int larter = Age + a;24 25             return larter;26         }27     }

 

     代理类是Aop框架自动生成的类,使用反编译工具我们可以看到,它比被代理类多了切面上下文声明(AspectContent)和相应的切面特性对象声明,在被代理类的方法执行前后,相应切面特性调用OnEntry、OnExit执行相关操作,如日志、参数验证、权限验证等等Aop功能,其中AspectContext是OnEntry、OnExit调用参数,如下:

public class AopTest_Proxy : AopTest{    public override string Name    {        get        {            object[] args = new object[0];            AspectContext aspectContext = new AspectContext(this, "get_Name", args);            LogAttribute logAttribute = new LogAttribute();            logAttribute.OnEntry(aspectContext);            string name = base.Name;            aspectContext.Result = name;            logAttribute.OnExit(aspectContext);            return name;        }        set        {            AspectContext context = new AspectContext(this, "set_Name", new object[]            {                value            });            LogAttribute logAttribute = new LogAttribute();            logAttribute.OnEntry(context);            base.Name = value;            logAttribute.OnExit(context);        }    }    public override int Age    {        get        {            object[] args = new object[0];            AspectContext aspectContext = new AspectContext(this, "get_Age", args);            LogAttribute logAttribute = new LogAttribute();            logAttribute.OnEntry(aspectContext);            int age = base.Age;            aspectContext.Result = age;            logAttribute.OnExit(aspectContext);            return age;        }        set        {            AspectContext context = new AspectContext(this, "set_Age", new object[]            {                value            });            LogAttribute logAttribute = new LogAttribute();            logAttribute.OnEntry(context);            base.Age = value;            logAttribute.OnExit(context);        }    }    public AopTest_Proxy(string name, int age) : base(name, age)    {    }    public override int NYearLater(int num)    {        AspectContext aspectContext = new AspectContext(this, "NYearLater", new object[]        {            num        });        LogAttribute logAttribute = new LogAttribute();        logAttribute.OnEntry(aspectContext);        int num2 = base.NYearLater(num);        aspectContext.Result = num2;        logAttribute.OnExit(aspectContext);        return num2;    }}

 

二、测试方法

public static void Test(){  try  {     AopTest WithPara = DynamicProxy.Create
("lxl", 10); ; WithPara.NYearLater(10); Console.WriteLine("done..."); } catch (Exception ex) { Console.WriteLine(ex.Message); } }

 

测试方法中:AopTest WithPara = DynamicProxy.Create<AopTest>("lxl", 10); ,生成一个代理对象,其他就正常使用就可以了。

调用测试方法执行结果如下:

Log OnEntry:set_Name(lxl)Log OnExit: set_NameLog OnEntry:set_Age(10)Log OnExit: set_AgeLog OnEntry:NYearLater(10)Log OnEntry:get_Age()Log OnExit: get_Age Result: 10Log OnExit: NYearLater Result: 20done...

 

   通过结果可以看到 属性Name、Age的Set方法,NYearLater方法,以及Age属性的Get方法都实现了日志记录。下边将分几篇来详细介绍DynamicProxy类的实现。欢迎大家多多指正、交流。

 

转载于:https://www.cnblogs.com/accode/p/10900711.html

你可能感兴趣的文章
代理模式
查看>>
AC日记——背包问题 V2 51nod 1086
查看>>
CSS关键字
查看>>
UIAlertView
查看>>
ES6快速入门(三)类与模块
查看>>
赛博web
查看>>
Java动手动脑第四讲课堂作业
查看>>
PowerDesigner 数据建模技术视频教程
查看>>
Webpack 开发服务器代理设置解决跨域问题
查看>>
Solr 15 - Solr添加和更新索引的过程 (文档的路由细节)
查看>>
DOS命令
查看>>
Oracle merge基本使用
查看>>
03-树1 树的同构
查看>>
第九周周记
查看>>
AdvStringGrid入门使用
查看>>
C#图像处理——ImageProcessor
查看>>
NOI2004 降雨量
查看>>
WPF的TextBox水印效果详解
查看>>
oracle启动服务和监听命令
查看>>
毒药和酒
查看>>