在.NET 3.5中,我将使用System.Reflection来使用AOP(可能是在Castle的Windsor Interceptors的上下文中)来定义需要在方法级别执行哪些安全操作等。我听说Reflection的某些部分很慢(我读过MSDN关于它的文章),并且希望缓存这些部分(无论如何,当我接近生产代码时)。我想验证我的方法:
- 缓存键为{type}+{区分大小写的方法名称}+}参数类型列表}
- 缓存键对象可以通过Equals操作进行比较
- 缓存负载是{MethodInfo}+{在方法上定义的自定义属性列表}
- 缓存通过构造函数注入注入到我的拦截器
- 缓存可以长期维护(基于我不会编写自修改代码的假设;-)
更新:
我不打算通过反射来调用方法——这是我自己写的;只是(目前)在我想要注入功能的属性上查找属性,其中属性定义了要注入的行为。我的拦截器目前将使用Castle的Windsor IInterceptor机制,直到我注意到改变它的原因。
显式调用MethodInfo确实很慢,但如果将其转换为委托,则可以使其更快。例如,请参阅此博客文章。当然,这对查找方法等没有帮助,但如果你要重复调用该方法,那么值得记住。
缓存键听起来很容易构建——类型和字符串比较起来很好也很容易。值总是相对简单:)
一旦建立,缓存将是只读的吗?你能把这些阶段分开吗,这样你就可以保证它在完全构建之前不会被阅读吗?如果是这样的话,您应该能够在没有任何显式锁定的情况下逃脱——基本上是从自定义键类型到自定义值类型的字典。
我同意Jon的大部分帖子——这是字典中的一个小注释:从性能的角度来看,您可能希望将其作为基准,而不仅仅是一个平面列表。上次我做了一个基准测试(字典与平面列表,检查每个项目直到找到匹配项),(读取访问)的分界点大约是150个项目;在这之后,列表会更快(只是因为简单)。但你自己做测试。。。(我手头没有数字来证明这一点)。
根据代码的不同,您可能能够使用泛型来进一步拆分数据,即缓存,以便类型T的所有信息都在一个位置,填充在缓存的静态ctor中。这可能是可能的,也可能不是,具体取决于体系结构。
最后,它可能适合也可能不适合,但有一些现有的AOP框架,如PostSharp,可能有助于简化注入点。
关于泛型点-(在init代码中)为Cache方法上的方法创建一个类型化委托会相当容易,以减少它需要扫描的数据量-只需要一点Type.MakeGenericType和delegate.CreateDelegate-在这一点之后,代码只知道您的Func<…>委托,并且不需要关心实现。