2010-04-23 35 views
1

我试图想出一种方法(静态或实例)方法调用可以拦截动态代理。我想实现它作为c#扩展方法但坚持如何生成静态方法的动态代理。是否有可能在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等)。

谢谢!

+2

不要。只要避免静态类。坚持通过接口抽象的实例类,你会更快乐。哦,你可以拦截那些。 – 2010-04-23 05:59:10

回答

7

完全不可能。

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

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

(技术上有非虚方法解决方法是从MarshalByRefObject派生类,但是基于远程的解决方案,这是缓慢和笨重,仍然不支持静态方法。)

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

+0

@Downvoter:我很想听听这个。你有更好的答案? – Aaronaught 2010-04-23 02:33:19

+0

您能否提供有关非虚拟方法的解决方法的更多细节?它将工作代理列表上的添加方法? – Maslow 2011-04-09 15:19:46

+0

@Maslow:我可以回答这个问题,但我会为你做一个伤害。 '列表'实现'IList ',所以你不应该试图代理类本身;设计你的代码总是使用'IList ',并且从你自己的定制实现开始,或者当你需要这个行为的时候只需要包装'List '。 – Aaronaught 2011-04-09 15:48:15

0

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

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

我在开源NConcern AOP Framework上工作。

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

它可以完成其工作的虚拟方法,非虚拟方法和静态方法没有任何工厂模式和继承的需要。

我的建议是避免使用AOP来“猴子补丁”,而静态方法只能是“单身使用快捷方式”,而不是主流。

在你的情况下,使用单身模式和静态方法作为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(); 
相关问题