如何在C#中创建一个简单的动态代理

AK_*_*AK_ 49 .net c# reflection proxy aop

我想构建一个动态代理对象来向对象添加某些功能.

基本上我想接收一个对象,用一个看起来与我原来的相同的对象包装它,并拦截所有的调用.

class Wrapper : DynamicProxy// dynamic proxy is not a reall class, but i guess something like this exists...
{
    public static T Wrap(T obj)
    {
        return (T) new Wrapper(obj);
    }

    public override object InterceptCall(MethodInfo info, object[] args)
    {
        // do stuff
    }

}
Run Code Online (Sandbox Code Playgroud)

为了澄清,我想做一些类似于WCF渠道工厂的事情......


我正在添加一个赏金,因为我需要一个很好的方法来代理类(不是接口)和处理非虚方法(就像我继承并在"new"关键字下添加了一个methond).我确信这一切都很可能,因为.Net就是这么做的.

alb*_*jan 37

您可以使用DynamicObjectImpromptuInterface的组合来完成此操作,但您必须具有实现要代理的功能和属性的接口.

public interface IDoStuff
{
    void Foo();
}

public class Wrapper<T> : DynamicObject
{
    private readonly T _wrappedObject;

    public static T1 Wrap<T1>(T obj) where T1 : class
    {
        if (!typeof(T1).IsInterface)
            throw new ArgumentException("T1 must be an Interface");

        return new Wrapper<T>(obj).ActLike<T1>();
    }

    //you can make the contructor private so you are forced to use the Wrap method.
    private Wrapper(T obj)
    {
        _wrappedObject = obj;
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        try
        {
            //do stuff here

            //call _wrappedObject object
            result = _wrappedObject.GetType().GetMethod(binder.Name).Invoke(_wrappedObject, args);
            return true;
        }
        catch
        {
            result = null;
            return false;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你当然可以选择失去类型安全性,然后像我展示的那样使用DynamicObject,然后放弃鸭子铸造.

我制作了这个对象代理的transparant可扩展版本,并在此处开源.


AK_*_*AK_ 14

我应该早点写出来,但没关系.

我的问题有一个特殊的"问题"我需要能够代理类而不是接口.

有两种解决方案:

  1. 真正的代理和朋友,基本上意味着使用.Net Remoting.需要一个从ContextBoundObject继承.

  2. 使用System.Reflection.Emit构建代理,如Spring所做,您还可以查看其ProxyFactoryObject的代码.这里有另一个 3 主题.

顺便说一下,第二种方法有相当大的限制,你不能代理非虚方法.


Dej*_*jan 7

.NET 6.0 在命名空间中添加了一个新的候选者ReflectionDispatchProxy该团队在此宣布这一消息。文章中包含示例用法。


Nei*_*ilD 5

看看PostSharp.我不知道如何在vanilla .Net中执行您想要的操作,但PostSharp提供的内容类似于"OnMethodBoundaryAspect",可用于替换或包装方法内的代码.

我用它来做日志,参数验证,异常处理等事情.

有一个免费的社区版,应该适合你.您需要在开发计算机上安装它,以及您使用的任何构建服务器.