是否可以在C#中为静态类或静态方法生成动态代理?

时间:2010-04-23 02:07:54

标签: c# aop castle-dynamicproxy

我试图通过动态代理提出一种方法(静态或实例)方法调用拦截。我希望将其实现为c#扩展方法,但坚持如何为静态方法生成动态代理。

一些用法:

Repository.GetAll<T>().CacheForMinutes(10);
Repository.GetAll<T>().LogWhenErrorOccurs();

//or     
var repo = new Repository();
repo.GetAll<T>().CacheForMinutes(10);
repo.GetAll<T>().LogWhenErrorOccurs();

我对任何图书馆(linfu,castle.dynamic proxy 2等)开放。

谢谢!

2 个答案:

答案 0 :(得分:9)

完全不可能。

实际上,代理甚至无法在所有实例方法上生成 - 它们必须是虚拟的,因此代理生成器可以创建派生类并覆盖它们。

静态方法永远不是虚拟的,因此不能被代理覆盖。

(从技术上讲,非虚拟方法的解决方法是从MarshalByRefObject派生类,但基于远程处理的解决方案很慢且很笨重,但仍然不支持静态方法。)

鉴于您的类名为Repository,我建议您改为使用这些方法实例方法。这些类型的操作通常不应该static开始。如果你制作它们static,你会失去很多东西:松耦合,模拟,依赖注入,一定数量的单元可测试性,以及 - 正如你刚刚发现的那样 - 代理和拦截。

答案 1 :(得分:0)

不可能采用常见的拦截策略。

但是大多数在编译时工作的AOP框架都可以做到。 (例如:PostSharp)

我在开源NConcern AOP Framework上工作。

这是一个简单的.NET AOP框架,允许通过交换方法在运行时进行拦截。

它可以完成虚拟方法,非虚方法和静态方法的工作,而无需任何工厂模式和继承需求。

我的建议是避免使用AOP来对抗猴子补丁&#34;和静态方法必须只是&#34;单例用法快捷方式&#34;而不是主流。

在你的情况下,使用单例模式和静态方法作为shortcup和DI(依赖注入)更容易实现简单的代理模式。

示例:

接口

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();