简体   繁体   中英

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.

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).

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.)

Given that your class is named Repository , I'm going to suggest that you make these methods instance methods instead. These kinds of operations generally shouldn't be static to begin with. 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.

Impossible with common interception strategies.

But most of AOP Framework working at compile time can do it. (example : PostSharp)

I work on an open source NConcern AOP Framework .

This is a simple .NET AOP Framework allowing interception at runtime by swaping methods.

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.

in your case it is easier to use singleton pattern with static methods as shortcup and DI (Dependency Injection) to enable easy proxy pattern.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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