[13年迁移] C# yAspectF,轻量级的aop实现,编入分离阻断
介绍一下AspectF这个东西,诞生于一位微软mvp之手,介绍它首先要从c#说起,当引入了委托这个概念的时候,它也只是c++的函数指针的封装而 已,但是后续陆续引入的lambda表达式,匿名方法,泛型,扩展方法语法糖,让其一次又一次的升华,一切都是如此美妙,可以说如果我把泛型的封装再做上 去,这个框架基本就可以代表近期c#的新特征的一个集合.在不用反射或者编译优化,这些解释器的手段,可以说c#应该是最好,抽象程度最高的高级语言了 (如果用的话就是java好,不过那些都是写生涩的技术,所以java的企业级框架,如此的强大)
1 public class AspectF 2 {//泛型的封装太麻烦,而且暂时用不到,故只根据需要做个string的 3 //在AspectF上加入了前阻断,并修改返回值,你要抛错也是行的 4 public delegate string yson(string i); 5 public delegate string yDelegate(yson work,string i); 6 public yDelegate yChain = null; 7 /// <summary> 8 /// 如果方面在work前面返回值了不是null的值,那么阻断,后面的话 9 /// </summary> 10 [DebuggerStepThrough] 11 public AspectF yCombine(yDelegate newAspectReturnDelegate) 12 { 13 if (this.yChain == null) 14 { 15 this.yChain = newAspectReturnDelegate; 16 } 17 else 18 { 19 yDelegate existingChain = this.yChain; 20 yDelegate callAnother = (work,i) => 21 existingChain((ii) => newAspectReturnDelegate(work,ii),i); 22 this.yChain = callAnother; 23 } 24 return this; 25 } 26 [DebuggerStepThrough] 27 public string yReturn(Func<string> work) 28 { 29 if (this.yChain == null) 30 { 31 return work(); 32 } 33 else 34 { 35 var returnValue = string.Empty; 36 this.yChain((i) => 37 {//每个yDelegate的匿名方法参数都再执行一次自己的work委托,同时加一个标识,说明是后执行,那么就不在执行这里的work委托, 38 //那么后修改返回值就出来了,而委托链之间,直接用它们自己的返回值了递归传获得的执行结果,由里到外的获得结果,用来调用, 39 //比如work("根据返回值后修改",代表执行后的常量) 40 if (i != null) {//判定泛型封装用define(T) 41 returnValue = i; 42 return returnValue; 43 } 44 returnValue= work();//执行这个 45 return returnValue; 46 },null);//泛型的话,这里传入define(T)即可 47 return returnValue; 48 } 49 } 50 } 51 class Program 52 { 53 static void Main(string[] args) 54 { 55 56 Console.WriteLine("最后返回"+saaddsad()); 57 } 58 public static string saaddsad() { 59 return AspectF.Define 60 .aPointer() 61 .bPointer() 62 .yReturn(() => 63 { 64 var ddd="执行方法"; 65 Console.WriteLine(ddd); 66 return ddd; 67 }); 68 } 69 } 70 static class AspectFExt 71 {//语法糖的扩展类,怎么用不到呢?好像只能系统的? 72 public static AspectF aPointer(this AspectF aspect) 73 { 74 75 return aspect.yCombine((work,i) => 76 { 77 Console.WriteLine("a切点前"); 78 string a= work("截断改变"); 79 Console.WriteLine("a切点后"+a); 80 work("a"); 81 return "da"; 82 }); 83 } 84 public static AspectF bPointer(this AspectF aspect) 85 { 86 //一个需要(func<string>)的方法,判断如果work指向底层,就执行一个空的 87 return aspect.yCombine((work,i) => 88 { 89 Console.WriteLine("b切点前"); 90 string b = work(i);//不想改变就返回i参数即可,不要使用null 91 Console.WriteLine("b切点后"+b); 92 return "fsa"; 93 }); 94 } 95 }
还能实现执行后获得返回值,然后改变,执行前改变,泛型封装的话,委托和匿名方法的约束写起来估计是比较烦的,也还有点小问题.,项目就用到前阻断,并改变返回值,那就这样吧,其实只要再执行一个work,然后给一个标识,就能实现后阻断,然后根据返回值再修改并传递,修改一下yReturn方法就行了.小型项目就不需要去借助企业框架,虽然编入的方式只能手动,不过效率是大型框架不能比的.
如果我也能就钻研一门语言,专心做一门学问,或者一项工艺,无疑是幸福的吧,有一天一定要把你们全部画出来.也许最近的伤感就是项目的后台要做完了,分离的日子越来越近了..C#不舍得啊..但是js又在等着我.我依然前行,因为有很多未知的奇迹在等着我.