https://files.cnblogs.com/guaiguai/FuncTest.zip
这个小例子可以看作方法级的AOP, 包里是一种实现方法, 利用了新的Expression, 比起生成动态代理类的做法那是清凉多了(当然, 也可以以这个为基础, 组合出复杂的方式,或者和生成动态代理类互补), 使用起来也灵活, 就是表达方式有点丑, 比如这样:
string c = "fuck";
MethodCall.Extract(() => bar.DoSomething(c)).Invoke();
MethodCall.Extract(() => bar.DoSomething(c)).Invoke();
有返回时(上面的DoSomething是实例的方法, 下面这个是静态方法):
int a = 3;
int b = 4;
List<int> list1 = MethodCall.Extract(() => Foo.DoSomething(a, "hello", b)).FromCache().Invoke();
int b = 4;
List<int> list1 = MethodCall.Extract(() => Foo.DoSomething(a, "hello", b)).FromCache().Invoke();
其中使用“()=>”这样的表达式写法是为了提取足够的信息, 包括方法、 实例和参数, FromCache这样的东西当然要自己扩展啦, 上面的包里有一个简单的例子; 而Invoke则触发它执行。
其实FromCache这样的Extension并不好, 如果这样扩展,那么使用时“FromCache().Log().CheckAccess().....Invoke()”这样臃肿的写法就会大量重复; 这里我有一个重构的方式, 不过想先听听大家的意见, 所以暂时卖个关子。
上面提到的重构,还有帮助组合的辅助设施,包括搭配使用的动态代理类生成器, 我暂时都不打算实现, 做全了工作量比较大, 同时很可能就又成了一个框架了。 最近一段时间,我个人对框架式的做法比较谨慎, 拿出这个轻薄短小的例子, 也是想先讨论一下。
这是跟老赵还有脑袋讨论的成果,其中Emit生成方法快速调用部分是1、2年前参照卢彦的例子改的(可以单独用到其它场合,不保证没有Bug哦)。脑袋其实不赞成用Emit干活的方式, 我个人同意脑袋的意见; 不过呢, 这个东西也不是完全没用, 放出来抛砖引玉吧。
这个解法的关键代码, 脑袋的“蛮力”解法, 以及这种解法和“蛮力”法之间的区别, 等时间多点一并分析。这个实现和其中的例子都比较草, 基本还是试验级别的,如果有问题可以给我留言。
Update:
做了几个测试, 发现对表达式可能出现的情况估计不足, 很多情况没有处理; 同时取表达式中的值使用了FieldInfo和PropertyInfo的GetValue, 如果执行次数很多, 效率不行(这个问题好解决, 也是用Emit生成快速调用的方法即可)。 大家暂时当例子看看, 我稍后会更新这些代码, 上面的包已经更新了一次, 添加了UnaryExpression作为参数的方法的支持:
jl_Block bundle = MethodCall.Extract(
() => dc.jl_Blocks.Single(
(x) => x.ForumID == s.SectionID)
).FromCache().Invoke();
() => dc.jl_Blocks.Single(
(x) => x.ForumID == s.SectionID)
).FromCache().Invoke();
看起来是不是稍微有点变态了? =) 事实上我觉得这样写还是不够爽, 如果变成这样:
jl_Block bundle = Cache(
() => dc.jl_Blocks.Single(
(x) => x.ForumID == s.SectionID)
)();
//或者这样
jl_Block bundle = Cache(
() => dc.jl_Blocks.Single
)((x) => x.ForumID == s.SectionID);
() => dc.jl_Blocks.Single(
(x) => x.ForumID == s.SectionID)
)();
//或者这样
jl_Block bundle = Cache(
() => dc.jl_Blocks.Single
)((x) => x.ForumID == s.SectionID);
也许比较令人满意, 你觉得上面哪种比较好看呢?大家帮忙想想还有什么比较爽的写法吧。当然, 能不能实现就是另外一码事了 :P 另外, 已经照顾到的情况实际上还是很少的,当前版本肯定还有很多其它问题, 有闲趣的人不妨看看, 和我一起改进。