简体   繁体   English

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

[英]Is it possible to generate dynamic proxy for static class or static method in C#?

I am trying to come up with a way that (either static or instance) method calls can be intercepted by dynamic proxy. 我试图提出一种方法(静态或实例)方法调用可以被动态代理拦截 I want to implement it as c# extension methods but stuck on how to generate dynamic proxy for static methods. 我想将其实现为c# 扩展方法,但仍坚持如何为静态方法生成动态代理。

Some usages: 一些用法:

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

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

I am open to any library (linfu, castle.dynamic proxy 2 or etc). 我对任何图书馆(临fu,城堡,动态代理2等)开放。

Thanks! 谢谢!

Totally impossible. 完全不可能。

In fact, proxies can't even be generated on all instance methods - they have to be virtual, so that the proxy generator can create a derived class and override them. 实际上,甚至不能在所有实例方法上生成代理-它们必须是虚拟的,以便代理生成器可以创建派生类并覆盖它们。

Static methods are never virtual, and therefore, cannot be overridden by a proxy. 静态方法永远不会是虚拟的,因此不能被代理覆盖。

(Technically there's a workaround for non-virtual methods which is to derive the class from MarshalByRefObject , but remoting-based solutions to this are slow and clunky and still won't support static methods.) (从技术上讲,有一种针对非虚拟方法的解决方法,该方法是从MarshalByRefObject派生该类,但基于远程处理的解决方案缓慢且笨拙,并且仍不支持静态方法。)

Given that your class is named Repository , I'm going to suggest that you make these methods instance methods instead. 假设您的类名为Repository ,我将建议您改用这些方法的实例方法。 These kinds of operations generally shouldn't be static to begin with. 开始时,这类操作通常不应该是static If you make them static , you lose a lot of things: Loose coupling, mocking, dependency injection, a certain amount of unit testability, and - as you've just discovered - proxying and interception. 如果将它们设置为static ,则会丢失很多东西:松耦合,模拟,依赖项注入,一定量的单元可测试性,以及-正如您刚刚发现的-代理和拦截。

Impossible with common interception strategies. 常见的拦截策略不可能。

But most of AOP Framework working at compile time can do it. 但是大多数在编译时工作的AOP Framework都能做到。 (example : PostSharp) (例如:PostSharp)

I work on an open source NConcern AOP Framework . 我致力于一个开源的NConcern AOP框架

This is a simple .NET AOP Framework allowing interception at runtime by swaping methods. 这是一个简单的.NET AOP框架,允许在运行时通过交换方法进行拦截。

It can do its job for virtual methods, non virtual methods and static method without any factory pattern and inheritance needs. 它可以为虚拟方法,非虚拟方法和静态方法完成其工作,而无需任何工厂模式和继承需求。

My recommandation is avoid use AOP to "monkey patch" and static methods must be only "singleton usages shortcut", not a mainstream. 我的建议是避免使用AOP进行“猴子补丁”,并且静态方法必须仅是“单个用法的快捷方式”,而不是主流。

in your case it is easier to use singleton pattern with static methods as shortcup and DI (Dependency Injection) to enable easy proxy pattern. 在您的情况下,更容易在静态方法(如shortcup和DI(依赖注入))中使用单例模式来启用简单的代理模式。

Example : 范例:

interface 接口

public interface IRepository
{
    IQueryable<T> Query<T>()
        where T : class;
}

the sugar using DI (via a factory) 用去离子糖(通过工厂)

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

Usage 用法

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM