如何用C#制作一个简单的动态代理
我想构建一个动态代理对象来向对象添加某些功能。
基本上我想接收一个对象,用一个看起来与我得到的原始对象相同的对象包装它,并拦截所有调用。
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 通道工厂的事情...
我添加了一个赏金,因为我需要一种好的方法来代理类(而不是接口)并处理非虚拟方法(就好像我继承并在“new”关键字下添加了一个方法)。 我确信这一切都是有可能的,因为 .Net 就是这么做的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
除了Castle.DynamicProxy之外,还有LinFu.DynamicProxy 上 Github。
In addition to Castle.DynamicProxy, there is also LinFu.DynamicProxy on Github.
我应该早点写这篇文章,但没关系。
我的问题有一个特殊的“陷阱”,我需要能够代理类而不是接口。
有两种解决方案:
RealProxy 和朋友,基本上意味着使用 .NET Remoting。需要从 ContextBoundObject 继承。
(经过硬编码以专门识别
RealProxy
),让您“覆盖”非虚拟成员.使用 System.Reflection.Emit 构建代理 由 spring 你也可以看看他们的代码 ProxyFactoryObject。这里有另外三个关于 href="http://weblogs.asp.net/seanmcalinden/archive/2010/03/18/creating-a-dynamic-proxy-generator-part-1-creating-the- assembly-builder-module-builder-and -caching-mechanism.aspx" rel="nofollow noreferrer">主题。
虚拟
成员。I should have written this sooner, but never mind.
My issue had a special "gotcha" I needed to be able to proxy classes and not interfaces.
There are two solutions to this:
RealProxy and friends, basically means using .NET Remoting. Requires one to inherit from ContextBoundObject.
(which is hardcoded to specifically recognize
RealProxy
) to let you "override" non-virtual members.Building a proxy using System.Reflection.Emit as done by spring you can also look at the code of their ProxyFactoryObject. Here are another three articles on the subject.
virtual
members..NET 6.0 向
Reflection
命名空间添加了一个新的候选者:DispatchProxy。该团队在此处宣布这一消息。文章中包含示例用法。.NET 6.0 has added a new candidate to the
Reflection
namespace: the DispatchProxy. The team is announcing it here. A sample usage is contained in the article.看看 PostSharp。
我不知道在 vanilla .Net 中如何做你想做的事情,但是 PostSharp 提供了诸如“OnMethodBoundaryAspect”之类的东西,它可以用来替换或包装方法内的代码。
我用它来做日志记录、参数验证、异常处理等事情。
有一个免费的社区版,它应该适合您。您需要将其安装在您的开发计算机以及您使用的任何构建服务器上。
Take a look at PostSharp.
I don't know of a way to do what you want in vanilla .Net, but PostSharp offers things like "OnMethodBoundaryAspect" which can be used to either replace or wrap the code inside the method.
I've used it to do things like logging, parameter validation, exception handling etc.
There is a free Community Edition, which should work for you. You'll need it installed on your development machine, as well as any build server that you use.
另一个选项是
ContextBoundObject
。大约 8-9 年前,CodeProject 上有一篇文章使用这种方法来跟踪方法调用。
Another option is
ContextBoundObject
.There was an article on CodeProject about 8-9 years back using this approach to trace method calls.
您可以仅使用 System.Danymic 命名空间中的 DynamicObject 来完成此操作,而无需使用任何第三方库。
示例代码:
然后在驱动程序类上:
这样,您可以设置和获取具有访问控制的字段。
You could do this with just DynamicObject from System.Danymic namespace, without using any third party libraries.
Example code:
Then on the driver class:
That way, you can set and get the fields with access control.
要在类中的每个函数之前和之后添加任何功能,真实代理是一个很好的方法。
所以现在 T 中可以是任何 TestClass。像这样为 TestClass 创建实例 -
var _instance=(object)DynamicProxy(TestClass).GetTransparentProxy();
动态代理的代码-
For adding any functionality before and after of every function in a class, Real proxy is a good approach.
So now in T can be any TestClass. Create Instance like this for TestClass-
var _instance=(object)DynamicProxy(TestClass).GetTransparentProxy();
The code for Dynamic Proxy-
您无法拦截对静态成员、非虚拟成员或私有成员的所有调用,除非您让 CLR 挂钩对该对象的每个方法/属性调用,并将调用重定向到您创建的假成员。您可以通过使用 .NET Profiler API。例如,TypeMock Isolator 使用它监视应用程序的执行,并且当调用方法时,CLR 通知 typemock isolator,这允许 Isolator 完全覆盖原始类。
You can't intercept all calls for static, not virtual, or private members unless you get the CLR to hooks into each every method/property call to that object and redirect call to fake one you created. You can achieve that by using the .NET Profiler API. TypeMock Isolator for example uses it monitor an application's execution and when method is called, CLR notifies typemock isolator which allows Isolator to override the original class completely.
您可以结合使用 DynamicObject 和 < a href="https://github.com/ekonbenefits/impromptu-interface" rel="noreferrer">ImpromptuInterface 但您必须有一个接口来实现您想要代理的功能和属性。
您当然可以选择失去类型安全性并使用像我所示的 DynamicObject ,然后放弃鸭子铸造。
我制作了该对象代理的透明可扩展版本,并在此处将其开源。
You could do this with a combination of DynamicObject and ImpromptuInterface but you will have to have an Interface that implements the functions and properties you want to proxy.
You could of course choose to lose the type-safety and go with a
DynamicObject
like I showed and then drop the duck-casting.I made a transparant extendible version of this object proxy, and open-sourced it here.