我试图想出一种方法,使(无论是静态的还是实例的)方法调用能够被动态代理拦截。我想将其实现为c# 扩展方法,但仍然停留在如何为静态方法生成动态代理上。
一些用法:
Repository.GetAll<T>().CacheForMinutes(10);
Repository.GetAll<T>().LogWhenErrorOccurs();
//or
var repo = new Repository();
repo.GetAll<T>().CacheForMinutes(10);
repo.GetAll<T>().LogWhenErrorOccurs();我向任何图书馆开放(林福,castle.dynamic代理2或其他)。
谢谢!
发布于 2010-04-23 02:29:06
完全不可能。
实际上,代理甚至不能在所有实例方法上生成--它们必须是虚拟的,这样代理生成器就可以创建派生类并覆盖它们。
静态方法从来不是虚拟的,因此不能被代理覆盖。
(从技术上讲,非虚拟方法是从MarshalByRefObject派生类的解决方案,但基于远程处理的解决方案速度慢且笨重,仍然不支持静态方法。)
考虑到您的类名为Repository,我建议您改用这些方法实例方法。这类操作通常不应该是static。如果让它们成为static,就会失去很多东西:松散耦合、模拟、依赖注入、一定数量的单元可测试性,以及--正如您刚刚发现的--代理和拦截。
发布于 2016-12-11 11:56:10
一般的拦截策略是不可能的。
但大多数AOP框架在编译时都能做到这一点。(例子: PostSharp)
我在一个开源NConcern AOP框架上工作。
这是一个简单的.NET AOP框架,允许通过交换方法在运行时进行拦截。
它可以完成虚拟方法、非虚拟方法和静态方法的工作,而无需任何工厂模式和继承需求。
我的命令是避免使用AOP来“猴子补丁”,静态方法只能是“单例使用捷径”,而不是主流。
在您的示例中,可以更容易地使用带有静态方法的单例模式,如短路和依赖注入(依赖项注入),以启用简单的代理模式。
例子:
接口
public interface IRepository
{
IQueryable<T> Query<T>()
where T : class;
}使用DI的糖(通过工厂)
static public class Repository
{
//You can wrap the interface (proxy) here if you need...
static private readonly IRepository m_Repository = MyDIFactory.Import<IRepository>();
static public IQueryable<T> Query<T>()
where T : class
{
return Repository.m_Repository.Query<T>();
}
}用法
Repository.Query<T>().CacheForMinutes(10);
Repository.Query<T>().LogWhenErrorOccurs();https://stackoverflow.com/questions/2695744
复制相似问题