如何在C#中创build一个简单的dynamic代理
我想要构build一个dynamic的代理对象来为某个对象添加某些function。
基本上我想接收一个对象,用一个看起来与我原来相同的对象包装它,并拦截所有的调用。
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 } }
只是为了澄清,我想做一些类似于WCF频道工厂…
我添加一个赏金,因为我需要一个很好的方法来代理类(而不是接口),并处理非虚拟方法(就像我inheritance和添加一个方法在“新”关键字下)。 我确信这一切都是非常可能的。
您可以使用DynamicObject和ImpromptuInterface的组合来实现此function,但必须具有实现要代理的函数和属性的接口。
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; } } }
你可以select失去types安全性,并像我展示的那样使用dynamic对象,然后放下鸭子。
我做了一个透明的可扩展版本的这个对象代理,并在这里打开它。
除了Castle.DynamicProxy 之外 , Github上还有LinFu.DynamicProxy 。
我应该早点写这个,但是没关系。
我的问题有一个特殊的“窍门”,我需要能够代理类而不是接口。
有两个解决scheme:
-
真正的代理和朋友,基本上意味着使用.Net Remoting。 需要一个从ContextBoundObjectinheritance。
-
像Spring一样使用System.Reflection.Emit构build代理,您还可以查看ProxyFactoryObject的代码。 这里还有三篇关于这个问题的 文章 。
顺便说一下,第二种方法有相当的限制,你不能代理非虚拟方法。
看看PostSharp 。 我不知道在vanilla.Net中做什么的方法,但是PostSharp提供了诸如“OnMethodBoundaryAspect”之类的东西,可以用来代替或者包装方法中的代码。
我用它来做日志,参数validation,exception处理等等。
有一个免费的社区版,应该为你工作。 您需要将它安装在您的开发机器上,以及您使用的任何构build服务器上。
这里是使用C#发送dynamic代理创build的简单示例
您也可以使用PostSharp之类的AOP框架
另一种select是ContextBoundObject
。
大约8-9年前,有一篇关于CodeProject的文章使用这种方法来跟踪方法调用。